Started work on actual attributed text. This includes the beginnings of an attributed text example. Now to implement.

This commit is contained in:
Pietro Gagliardi 2017-02-11 23:19:30 -05:00
parent c4a97792ea
commit 32a0284edc
6 changed files with 181 additions and 3 deletions

View File

@ -297,6 +297,11 @@ size_t uiAttributedStringGraphemeToByteIndex(uiAttributedString *s, size_t pos)
return pos; return pos;
} }
void uiAttributedStringSetAttribute(uiAttributedString *s, uiAttribute type, uintptr_t value, size_t start, size_t end)
{
attrlistInsertAttribute(s->attrs, type, value, start, end);
}
// TODO introduce an iterator? // TODO introduce an iterator?
void uiAttributedStringForEachAttribute(uiAttributedString *s, uiAttributedStringForEachAttributeFunc f, void *data) void uiAttributedStringForEachAttribute(uiAttributedString *s, uiAttributedStringForEachAttributeFunc f, void *data)
{ {

View File

@ -32,6 +32,7 @@ if(NOT WIN32)
endif() endif()
_add_example(drawtext _add_example(drawtext
drawtext/attributes.c
drawtext/basic.c drawtext/basic.c
drawtext/hittest.c drawtext/hittest.c
drawtext/main.c drawtext/main.c

View File

@ -0,0 +1,159 @@
// 11 february 2017
#include "drawtext.h"
static uiAttributedString *attrstr;
static void setupAttributedString(void)
{
size_t start, end;
const char *next;
attrstr = uiNewAttributedString("uiAttributedString isn't just for plain text! It supports ");
next = "multiple fonts";
start = uiAttributedStringLen(attrstr);
end = start + strlen(next);
uiAttributedStringAppendUnattributed(attrstr, next);
uiAttributedStringSetAttribute(attrstr,
uiAttributeFamily,
(uintptr_t) "Courier New",
start, end);
uiAttributedStringAppendUnattributed(attrstr, ", ");
next = "multiple sizes";
}
static char fontFamily[] = "Times New Roman";
// TODO should be const; look at constructor function?
static uiDrawFontDescriptor defaultFont = {
.Family = fontFamily,
.Size = 12,
.Weight = uiDrawTextWeightNormal,
.Italic = uiDrawTextItalicNormal,
.Stretch = uiDrawTextStretchNormal,
};
static uiDrawTextLayoutParams params;
#define margins 10
static uiBox *panel;
static uiCheckbox *showExtents;
static uiCheckbox *showLineBounds;
static uiCheckbox *showLineGuides;
// TODO should be const?
static uiDrawBrush fillBrushes[4] = {
{
.Type = uiDrawBrushTypeSolid,
.R = 1.0,
.G = 0.0,
.B = 0.0,
.A = 0.5,
},
{
.Type = uiDrawBrushTypeSolid,
.R = 0.0,
.G = 1.0,
.B = 0.0,
.A = 0.5,
},
{
.Type = uiDrawBrushTypeSolid,
.R = 0.0,
.G = 0.0,
.B = 1.0,
.A = 0.5,
},
{
.Type = uiDrawBrushTypeSolid,
.R = 0.0,
.G = 1.0,
.B = 1.0,
.A = 0.5,
},
};
static void draw(uiAreaDrawParams *p)
{
uiDrawPath *path;
uiDrawTextLayout *layout;
uiDrawBrush b;
b.Type = uiDrawBrushTypeSolid;
// only clip the text, not the guides
uiDrawSave(p->Context);
path = uiDrawNewPath(uiDrawFillModeWinding);
uiDrawPathAddRectangle(path, margins, margins,
p->AreaWidth - 2 * margins,
p->AreaHeight - 2 * margins);
uiDrawPathEnd(path);
uiDrawClip(p->Context, path);
uiDrawFreePath(path);
params.Width = p->AreaWidth - 2 * margins;
layout = uiDrawNewTextLayout(&params);
uiDrawText(p->Context, layout, margins, margins);
uiDrawRestore(p->Context);
if (uiCheckboxChecked(showLineBounds)) {
uiDrawTextLayoutLineMetrics m;
int i, n;
int fill = 0;
n = uiDrawTextLayoutNumLines(layout);
for (i = 0; i < n; i++) {
uiDrawTextLayoutLineGetMetrics(layout, i, &m);
path = uiDrawNewPath(uiDrawFillModeWinding);
uiDrawPathAddRectangle(path, margins + m.X, margins + m.Y,
m.Width, m.Height);
uiDrawPathEnd(path);
uiDrawFill(p->Context, path, fillBrushes + fill);
uiDrawFreePath(path);
fill = (fill + 1) % 4;
}
}
uiDrawFreeTextLayout(layout);
}
static struct example attributesExample;
// TODO share?
static void checkboxChecked(uiCheckbox *c, void *data)
{
redraw();
}
static uiCheckbox *newCheckbox(const char *text)
{
uiCheckbox *c;
c = uiNewCheckbox(text);
uiCheckboxOnToggled(c, checkboxChecked, NULL);
uiBoxAppend(panel, uiControl(c), 0);
return c;
}
struct example *mkAttributesExample(void)
{
panel = uiNewVerticalBox();
showLineBounds = newCheckbox("Show Line Bounds");
attributesExample.name = "Attributed Text";
attributesExample.panel = uiControl(panel);
attributesExample.draw = draw;
attributesExample.mouse = NULL;
attributesExample.key = NULL;
setupAttributedString();
params.String = attrstr;
params.DefaultFont = &defaultFont;
params.Align = uiDrawTextLayoutAlignLeft;
return &attributesExample;
}

View File

@ -20,3 +20,6 @@ extern struct example *mkBasicExample(void);
// hittest.c // hittest.c
extern struct example *mkHitTestExample(void); extern struct example *mkHitTestExample(void);
// attributes.c
extern struct example *mkAttributesExample(void);

View File

@ -110,6 +110,11 @@ int main(void)
uiControlHide(examples[n]->panel); uiControlHide(examples[n]->panel);
uiBoxAppend(box, examples[n]->panel, 0); uiBoxAppend(box, examples[n]->panel, 0);
n++; n++;
examples[n] = mkAttributesExample();
uiComboboxAppend(exampleList, examples[n]->name);
uiControlHide(examples[n]->panel);
uiBoxAppend(box, examples[n]->panel, 0);
n++;
// and set things up for the initial state // and set things up for the initial state
uiComboboxSetSelected(exampleList, 0); uiComboboxSetSelected(exampleList, 0);
uiComboboxOnSelected(exampleList, onExampleChanged, NULL); uiComboboxOnSelected(exampleList, onExampleChanged, NULL);

View File

@ -1,15 +1,19 @@
typedef struct uiAttributedString uiAttributedString; typedef struct uiAttributedString uiAttributedString;
_UI_ENUM(uiAttribute) { _UI_ENUM(uiAttribute) {
// TODO uiAttributeFamily, // TODO once we allow loading fonts in memory we can't use just one pointer anymore
// TODO uiAttributeSize, uiAttributeFamily,
// TODO no guarantee this can fit in a uintptr_t; we need a better way to store these...
uiAttributeSize,
uiAttributeWeight, uiAttributeWeight,
uiAttributeItalic,
uiAttributeStretch,
// TODO // TODO
// TODO uiAttributeSystem, // TODO uiAttributeSystem,
// TODO uiAttributeCustom, // TODO uiAttributeCustom,
}; };
typedef int (*uiAttributedStringForEachAttributeFunc)(uiAttributedString *, uiAttribute type, uintptr_t value, size_t start, size_t end, void *data); typedef int (*uiAttributedStringForEachAttributeFunc)(uiAttributedString *s, uiAttribute type, uintptr_t value, size_t start, size_t end, void *data);
// @role uiAttributedString constructor // @role uiAttributedString constructor
// uiNewAttributedString() creates a new uiAttributedString from // uiNewAttributedString() creates a new uiAttributedString from
@ -35,6 +39,7 @@ _UI_EXTERN void uiAttributedStringDelete(uiAttributedString *s, size_t start, si
_UI_EXTERN size_t uiAttributedStringNumGraphemes(uiAttributedString *s); _UI_EXTERN size_t uiAttributedStringNumGraphemes(uiAttributedString *s);
_UI_EXTERN size_t uiAttributedStringByteIndexToGrapheme(uiAttributedString *s, size_t pos); _UI_EXTERN size_t uiAttributedStringByteIndexToGrapheme(uiAttributedString *s, size_t pos);
_UI_EXTERN size_t uiAttributedStringGraphemeToByteIndex(uiAttributedString *s, size_t pos); _UI_EXTERN size_t uiAttributedStringGraphemeToByteIndex(uiAttributedString *s, size_t pos);
_UI_EXTERN void uiAttributedStringSetAttribute(uiAttributedString *s, uiAttribute type, uintptr_t value, size_t start, size_t end);
_UI_EXTERN void uiAttributedStringForEachAttribute(uiAttributedString *s, uiAttributedStringForEachAttributeFunc f, void *data); _UI_EXTERN void uiAttributedStringForEachAttribute(uiAttributedString *s, uiAttributedStringForEachAttributeFunc f, void *data);
typedef struct uiDrawFontDescriptor uiDrawFontDescriptor; typedef struct uiDrawFontDescriptor uiDrawFontDescriptor;