Browse Source

Added multi-line text drawing

- fixed some warnings
- changed nvgLetterSpacing() to nvgTextLetterSpacing()
- added nvgTextBox()
- added nvgTextLineHeight()
- added some documentation
shared-context
Mikko Mononen 11 years ago
parent
commit
635f4a4afb
3 changed files with 107 additions and 33 deletions
  1. +10
    -0
      example/demo.c
  2. +63
    -10
      src/nanovg.c
  3. +34
    -23
      src/nanovg.h

+ 10
- 0
example/demo.c View File

@@ -818,6 +818,7 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h
int nrows, i, nglyphs, j;
float lineh;
float caretx, px;
NVG_NOTUSED(height);

nvgSave(vg);

@@ -872,6 +873,15 @@ void drawParagraph(struct NVGcontext* vg, float x, float y, float width, float h
start = rows[nrows-1].next;
}

y += 10.0f;

nvgFillColor(vg, nvgRGBA(0,0,0,220));
nvgFontSize(vg, 12.0f);
nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP);
nvgTextLineHeight(vg, 1.2f);

nvgTextBox(vg, x,y, 150, "Hover your mouse over the text to see calculated caret position.", NULL);

nvgRestore(vg);
}



+ 63
- 10
src/nanovg.c View File

@@ -66,6 +66,7 @@ struct NVGstate {
struct NVGscissor scissor;
float fontSize;
float letterSpacing;
float lineHeight;
float fontBlur;
int textAlign;
int fontId;
@@ -290,13 +291,23 @@ struct NVGcolor nvgRGBf(float r, float g, float b)

struct NVGcolor nvgRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
struct NVGcolor color = {r/255.0f, g/255.0f, b/255.0f, a/255.0f};
struct NVGcolor color;
// Use longer initialization to suppress warning.
color.r = r / 255.0f;
color.g = g / 255.0f;
color.b = b / 255.0f;
color.a = a / 255.0f;
return color;
}

struct NVGcolor nvgRGBAf(float r, float g, float b, float a)
{
struct NVGcolor color = {r, g, b, a};
struct NVGcolor color;
// Use longer initialization to suppress warning.
color.r = r;
color.g = g;
color.b = b;
color.a = a;
return color;
}

@@ -466,6 +477,7 @@ void nvgReset(struct NVGcontext* ctx)

state->fontSize = 16.0f;
state->letterSpacing = 0.0f;
state->lineHeight = 0.0f;
state->fontBlur = 0.0f;
state->textAlign = NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE;
state->fontId = 0;
@@ -574,7 +586,7 @@ int nvgCreateImage(struct NVGcontext* ctx, const char* filename)
return image;
}

int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata, int freeData)
int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata)
{
int w, h, n, image;
unsigned char* img = stbi_load_from_memory(data, ndata, &w, &h, &n, 4);
@@ -616,7 +628,7 @@ struct NVGpaint nvgLinearGradient(struct NVGcontext* ctx,
struct NVGpaint p;
float dx, dy, d;
const float large = 1e5;
NVG_NOTUSED(ctx);
memset(&p, 0, sizeof(p));

// Calculate transform aligned to the line
@@ -655,7 +667,7 @@ struct NVGpaint nvgRadialGradient(struct NVGcontext* ctx,
struct NVGpaint p;
float r = (inr+outr)*0.5f;
float f = (outr-inr);
NVG_NOTUSED(ctx);
memset(&p, 0, sizeof(p));

nvg__xformIdentity(p.xform);
@@ -680,7 +692,7 @@ struct NVGpaint nvgBoxGradient(struct NVGcontext* ctx,
struct NVGcolor icol, struct NVGcolor ocol)
{
struct NVGpaint p;
NVG_NOTUSED(ctx);
memset(&p, 0, sizeof(p));

nvg__xformIdentity(p.xform);
@@ -706,7 +718,7 @@ struct NVGpaint nvgImagePattern(struct NVGcontext* ctx,
int image, int repeat)
{
struct NVGpaint p;
NVG_NOTUSED(ctx);
memset(&p, 0, sizeof(p));

nvg__xformRotate(p.xform, angle);
@@ -1873,16 +1885,22 @@ void nvgFontSize(struct NVGcontext* ctx, float size)
state->fontSize = size;
}

void nvgLetterSpacing(struct NVGcontext* ctx, float spacing)
void nvgFontBlur(struct NVGcontext* ctx, float blur)
{
struct NVGstate* state = nvg__getState(ctx);
state->fontBlur = blur;
}

void nvgTextLetterSpacing(struct NVGcontext* ctx, float spacing)
{
struct NVGstate* state = nvg__getState(ctx);
state->letterSpacing = spacing;
}

void nvgFontBlur(struct NVGcontext* ctx, float blur)
void nvgTextLineHeight(struct NVGcontext* ctx, float lineHeight)
{
struct NVGstate* state = nvg__getState(ctx);
state->fontBlur = blur;
state->lineHeight = lineHeight;
}

void nvgTextAlign(struct NVGcontext* ctx, int align)
@@ -1984,6 +2002,41 @@ float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, cons
return iter.x;
}

float nvgTextBox(struct NVGcontext* ctx, float x, float y, float width, const char* string, const char* end)
{
struct NVGstate* state = nvg__getState(ctx);
struct NVGtextRow rows[2];
int nrows = 0, i;
int oldAlign = state->textAlign;
int haling = state->textAlign & (NVG_ALIGN_LEFT | NVG_ALIGN_CENTER | NVG_ALIGN_RIGHT);
int valign = state->textAlign & (NVG_ALIGN_TOP | NVG_ALIGN_MIDDLE | NVG_ALIGN_BOTTOM | NVG_ALIGN_BASELINE);
float lineh = 0;

if (state->fontId == FONS_INVALID) return x;

nvgTextMetrics(ctx, NULL, NULL, &lineh);

state->textAlign = NVG_ALIGN_LEFT | valign;

while ((nrows = nvgTextBreakLines(ctx, string, end, width, rows, 2))) {
for (i = 0; i < nrows; i++) {
struct NVGtextRow* row = &rows[i];
if (haling & NVG_ALIGN_LEFT)
nvgText(ctx, x, y, row->start, row->end);
else if (haling & NVG_ALIGN_CENTER)
nvgText(ctx, x + width*0.5f - row->width*0.5f, y, row->start, row->end);
else if (haling & NVG_ALIGN_RIGHT)
nvgText(ctx, x + width - row->width, y, row->start, row->end);
y += lineh * state->lineHeight;
}
string = rows[nrows-1].next;
}

state->textAlign = oldAlign;

return 0; // TODO
}

int nvgTextGlyphPositions(struct NVGcontext* ctx, const char* string, const char* end, float x, float y, struct NVGglyphPosition* positions, int maxPositions)
{
struct NVGstate* state = nvg__getState(ctx);


+ 34
- 23
src/nanovg.h View File

@@ -27,20 +27,16 @@ extern "C" {

struct NVGcontext;

struct NVGcolor
{
union
{
struct NVGcolor {
union {
float rgba[4];
struct
{
struct {
float r,g,b,a;
};
};
};

struct NVGpaint
{
struct NVGpaint {
float xform[6];
float extent[2];
float radius;
@@ -91,6 +87,19 @@ enum NVGalpha {
NVG_PREMULTIPLIED_ALPHA,
};

struct NVGglyphPosition {
const char* str; // Position of the glyph in the input string.
float x; // The x- coordinate of the position of the glyph .
};

struct NVGtextRow {
const char* start; // Pointer to the input text where the row starts.
const char* end; // Pointer to the input text where the row ends (one past the last character).
const char* next; // Pointer to the beginning of the next row.
float width; // Width of the row.
};


// Begin drawing a new frame
// Calls to nanovg drawing API should be wrapped in nvgBeginFrame() & nvgEndFrame()
// nvgBeginFrame() defines the size of the window to render to in relation currently
@@ -243,9 +252,9 @@ void nvgScale(struct NVGcontext* ctx, float x, float y);
// Returns handle to the image.
int nvgCreateImage(struct NVGcontext* ctx, const char* filename);

// Creates image by loading it from the specified memory chunk.
// Creates image by loading it from the specified chunk of memory.
// Returns handle to the image.
int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata, int freeData);
int nvgCreateImageMem(struct NVGcontext* ctx, unsigned char* data, int ndata);

// Creates image from specified image data.
// Returns handle to the image.
@@ -394,12 +403,15 @@ int nvgFindFont(struct NVGcontext* ctx, const char* name);
// Sets the font size of current text style.
void nvgFontSize(struct NVGcontext* ctx, float size);

// Sets the letter spacing of current text style.
void nvgLetterSpacing(struct NVGcontext* ctx, float spacing);

// Sets the blur of current text style.
void nvgFontBlur(struct NVGcontext* ctx, float blur);

// Sets the letter spacing of current text style.
void nvgTextLetterSpacing(struct NVGcontext* ctx, float spacing);

// Sets the proportional line height of current text style. The line height is specified as multiple of font size.
void nvgTextLineHeight(struct NVGcontext* ctx, float lineHeight);

// Sets the text align of current text style, see NVGaling for options.
void nvgTextAlign(struct NVGcontext* ctx, int align);

@@ -412,6 +424,11 @@ void nvgFontFace(struct NVGcontext* ctx, const char* font);
// Draws text string at specified location. If end is specified only the sub-string up to the end is drawn.
float nvgText(struct NVGcontext* ctx, float x, float y, const char* string, const char* end);

// Draws multi-line text string at specified location wrapped at the specified width. If end is specified only the sub-string up to the end is drawn.
// White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
// Words longer than the max width are slit at nearest character (i.e. no hyphenation).
float nvgTextBox(struct NVGcontext* ctx, float x, float y, float width, const char* string, const char* end);

// Measures the specified text string. Parameter bounds should be a pointer to float[4] if
// the bounding box of the text should be returned. Returns the width of the measured text.
// Current transform does not affect the measured values.
@@ -421,18 +438,12 @@ float nvgTextBounds(struct NVGcontext* ctx, const char* string, const char* end,
// Current transform does not affect the measured values.
void nvgTextMetrics(struct NVGcontext* ctx, float* ascender, float* descender, float* lineh);

struct NVGglyphPosition {
const char* str;
float x;
};
// Calculates the glyph x positions of the specified text. If end is specified only the sub-string will be used.
int nvgTextGlyphPositions(struct NVGcontext* ctx, const char* string, const char* end, float x, float y, struct NVGglyphPosition* positions, int maxPositions);

struct NVGtextRow {
const char* start;
const char* end;
const char* next;
float width;
};
// Breaks the specified text into lines. If end is specified only the sub-string will be used.
// White space is stripped at the beginning of the rows, the text is split at word boundaries or when new-line characters are encountered.
// Words longer than the max width are slit at nearest character (i.e. no hyphenation).
int nvgTextBreakLines(struct NVGcontext* ctx, const char* string, const char* end, float maxRowWidth, struct NVGtextRow* rows, int maxRows);

//


Loading…
Cancel
Save