Set up a proper, formal layout and attirbute system. No attributes right now, but initial font style is in. Implemented it on GTK+.
This commit is contained in:
parent
4f2dbe2662
commit
ca514d94d1
78
test/page9.c
78
test/page9.c
|
@ -8,13 +8,7 @@ static uiCombobox *textWeight;
|
|||
static uiCombobox *textItalic;
|
||||
static uiCheckbox *textSmallCaps;
|
||||
static uiCombobox *textStretch;
|
||||
static uiEntry *textR, *textG, *textB, *textA;
|
||||
static uiCheckbox *textHasBackground;
|
||||
static uiEntry *textBR, *textBG, *textBB, *textBA;
|
||||
static uiCheckbox *textHasStrikethrough;
|
||||
static uiEntry *textSR, *textSG, *textSB, *textSA;
|
||||
static uiCheckbox *textHasUnderline;
|
||||
static uiEntry *textUR, *textUG, *textUB, *textUA;
|
||||
static uiCombobox *textGravity;
|
||||
static uiButton *textApply;
|
||||
static uiArea *textArea;
|
||||
static uiAreaHandler textAreaHandler;
|
||||
|
@ -32,11 +26,12 @@ static double entryDouble(uiEntry *e)
|
|||
|
||||
static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *dp)
|
||||
{
|
||||
uiDrawTextStyle style;
|
||||
uiDrawInitialTextStyle style;
|
||||
char *s;
|
||||
char *family; // make compiler happy
|
||||
uiDrawTextLayout *layout;
|
||||
|
||||
memset(&style, 0, sizeof (uiDrawTextStyle));
|
||||
memset(&style, 0, sizeof (uiDrawInitialTextStyle));
|
||||
family = uiEntryText(textFont);
|
||||
style.Family = family;
|
||||
style.Size = entryDouble(textSize);
|
||||
|
@ -44,27 +39,11 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *dp)
|
|||
style.Italic = uiComboboxSelected(textItalic);
|
||||
style.SmallCaps = uiCheckboxChecked(textSmallCaps);
|
||||
style.Stretch = uiComboboxSelected(textStretch);
|
||||
style.TextR = entryDouble(textR);
|
||||
style.TextG = entryDouble(textG);
|
||||
style.TextB = entryDouble(textB);
|
||||
style.TextA = entryDouble(textA);
|
||||
style.HasBackground = uiCheckboxChecked(textHasBackground);
|
||||
style.BackgroundR = entryDouble(textBR);
|
||||
style.BackgroundG = entryDouble(textBG);
|
||||
style.BackgroundB = entryDouble(textBB);
|
||||
style.BackgroundA = entryDouble(textBA);
|
||||
style.HasStrikethrough = uiCheckboxChecked(textHasStrikethrough);
|
||||
style.StrikethroughR = entryDouble(textSR);
|
||||
style.StrikethroughG = entryDouble(textSG);
|
||||
style.StrikethroughB = entryDouble(textSB);
|
||||
style.StrikethroughA = entryDouble(textSA);
|
||||
style.HasUnderline = uiCheckboxChecked(textHasUnderline);
|
||||
style.UnderlineR = entryDouble(textUR);
|
||||
style.UnderlineG = entryDouble(textUG);
|
||||
style.UnderlineB = entryDouble(textUB);
|
||||
style.UnderlineA = entryDouble(textUA);
|
||||
style.Gravity = uiComboboxSelected(textGravity);
|
||||
s = uiEntryText(textString);
|
||||
uiDrawText(dp->Context, 10, 10, s, &style);
|
||||
layout = uiDrawNewTextLayout(s, &style);
|
||||
uiDrawText(dp->Context, 10, 10, layout);
|
||||
uiDrawFreeTextLayout(layout);
|
||||
uiFreeText(s);
|
||||
uiFreeText(family);
|
||||
}
|
||||
|
@ -95,35 +74,6 @@ static void onTextApply(uiButton *b, void *data)
|
|||
uiAreaQueueRedrawAll(textArea);
|
||||
}
|
||||
|
||||
static void mkRGBA(uiBox *parent, uiCheckbox **has, const char *hasText, uiEntry **r, uiEntry **g, uiEntry **b, uiEntry **a, const char *field)
|
||||
{
|
||||
uiBox *hbox;
|
||||
|
||||
hbox = newHorizontalBox();
|
||||
uiBoxAppend(parent, uiControl(hbox), 0);
|
||||
|
||||
if (has != NULL) {
|
||||
*has = uiNewCheckbox(hasText);
|
||||
uiBoxAppend(hbox, uiControl(*has), 0);
|
||||
}
|
||||
|
||||
*r = uiNewEntry();
|
||||
uiEntrySetText(*r, field);
|
||||
uiBoxAppend(hbox, uiControl(*r), 1);
|
||||
|
||||
*g = uiNewEntry();
|
||||
uiEntrySetText(*g, field);
|
||||
uiBoxAppend(hbox, uiControl(*g), 1);
|
||||
|
||||
*b = uiNewEntry();
|
||||
uiEntrySetText(*b, field);
|
||||
uiBoxAppend(hbox, uiControl(*b), 1);
|
||||
|
||||
*a = uiNewEntry();
|
||||
uiEntrySetText(*a, "1.0");
|
||||
uiBoxAppend(hbox, uiControl(*a), 1);
|
||||
}
|
||||
|
||||
uiBox *makePage9(void)
|
||||
{
|
||||
uiBox *page9;
|
||||
|
@ -193,10 +143,14 @@ uiBox *makePage9(void)
|
|||
uiComboboxSetSelected(textStretch, uiDrawTextStretchNormal);
|
||||
uiBoxAppend(hbox, uiControl(textStretch), 1);
|
||||
|
||||
mkRGBA(vbox, NULL, NULL, &textR, &textG, &textB, &textA, "0.0");
|
||||
mkRGBA(vbox, &textHasBackground, "Background", &textBR, &textBG, &textBB, &textBA, "1.0");
|
||||
mkRGBA(vbox, &textHasStrikethrough, "Strikethrough", &textSR, &textSG, &textSB, &textSA, "0.0");
|
||||
mkRGBA(vbox, &textHasUnderline, "Underline", &textUR, &textUG, &textUB, &textUA, "0.0");
|
||||
textGravity = uiNewCombobox();
|
||||
uiComboboxAppend(textGravity, "South");
|
||||
uiComboboxAppend(textGravity, "East");
|
||||
uiComboboxAppend(textGravity, "North");
|
||||
uiComboboxAppend(textGravity, "West");
|
||||
uiComboboxAppend(textGravity, "Auto");
|
||||
uiComboboxSetSelected(textGravity, uiDrawTextGravitySouth);
|
||||
uiBoxAppend(hbox, uiControl(textGravity), 1);
|
||||
|
||||
textApply = uiNewButton("Apply");
|
||||
uiButtonOnClicked(textApply, onTextApply, NULL);
|
||||
|
|
29
ui.h
29
ui.h
|
@ -449,7 +449,8 @@ _UI_EXTERN uintmax_t uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff);
|
|||
_UI_EXTERN char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, uintmax_t n);
|
||||
_UI_EXTERN void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff);
|
||||
|
||||
typedef struct uiDrawTextStyle uiDrawTextStyle;
|
||||
typedef struct uiDrawTextLayout uiDrawTextLayout;
|
||||
typedef struct uiDrawInitialTextStyle uiDrawInitialTextStyle;
|
||||
|
||||
typedef enum uiDrawTextWeight {
|
||||
uiDrawTextWeightThin,
|
||||
|
@ -484,6 +485,25 @@ typedef enum uiDrawTextStretch {
|
|||
uiDrawTextStretchUltraExpanded,
|
||||
} uiDrawTextStretch;
|
||||
|
||||
typedef enum uiDrawTextGravity {
|
||||
uiDrawTextGravitySouth,
|
||||
uiDrawTextGravityEast,
|
||||
uiDrawTextGravityNorth,
|
||||
uiDrawTextGravityWest,
|
||||
uiDrawTextGravityAuto,
|
||||
} uiDrawTextGravity;
|
||||
|
||||
struct uiDrawInitialTextStyle {
|
||||
const char *Family;
|
||||
double Size;
|
||||
uiDrawTextWeight Weight;
|
||||
uiDrawTextItalic Italic;
|
||||
int SmallCaps;
|
||||
uiDrawTextStretch Stretch;
|
||||
uiDrawTextGravity Gravity;
|
||||
};
|
||||
|
||||
/*TODO
|
||||
struct uiDrawTextStyle {
|
||||
const char *Family;
|
||||
double Size;
|
||||
|
@ -513,12 +533,15 @@ struct uiDrawTextStyle {
|
|||
const char *Language; // RFC 3066; NULL for default
|
||||
// TODO other Pango attributes
|
||||
};
|
||||
*/
|
||||
|
||||
_UI_EXTERN double uiDrawTextSizeToPoints(double textSize);
|
||||
_UI_EXTERN double uiDrawPointsToTextSize(double points);
|
||||
|
||||
// TODO make this more robust.
|
||||
_UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, const char *text, uiDrawTextStyle *style);
|
||||
_UI_EXTERN uiDrawTextLayout *uiDrawNewTextLayout(const char *text, const uiDrawInitialTextStyle *initialTextStyle);
|
||||
_UI_EXTERN void uiDrawFreeTextLayout(uiDrawTextLayout *layout);
|
||||
|
||||
_UI_EXTERN void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout);
|
||||
|
||||
typedef enum uiModifiers {
|
||||
uiModifierCtrl = 1 << 0,
|
||||
|
|
94
unix/draw.c
94
unix/draw.c
|
@ -531,45 +531,65 @@ static const PangoStretch pangoStretches[] = {
|
|||
[uiDrawTextStretchUltraExpanded] = PANGO_STRETCH_ULTRA_EXPANDED,
|
||||
};
|
||||
|
||||
void uiDrawText(uiDrawContext *c, double x, double y, const char *text, uiDrawTextStyle *style)
|
||||
static const PangoGravity pangoGravities[] = {
|
||||
[uiDrawTextGravitySouth] = PANGO_GRAVITY_SOUTH,
|
||||
[uiDrawTextGravityEast] = PANGO_GRAVITY_EAST,
|
||||
[uiDrawTextGravityNorth] = PANGO_GRAVITY_NORTH,
|
||||
[uiDrawTextGravityWest] = PANGO_GRAVITY_WEST,
|
||||
[uiDrawTextGravityAuto] = PANGO_GRAVITY_AUTO,
|
||||
};
|
||||
|
||||
// note: PangoCairoLayouts are tied to a given cairo_t, so we can't store one in this device-independent structure
|
||||
struct uiDrawTextLayout {
|
||||
char *s;
|
||||
PangoFontDescription *desc;
|
||||
};
|
||||
|
||||
uiDrawTextLayout *uiDrawNewTextLayout(const char *text, const uiDrawInitialTextStyle *initialStyle)
|
||||
{
|
||||
PangoAttrList *attrs;
|
||||
PangoLayout *layout;
|
||||
uiDrawTextLayout *layout;
|
||||
PangoVariant variant;
|
||||
|
||||
attrs = pango_attr_list_new();
|
||||
pango_attr_list_insert(attrs,
|
||||
pango_attr_family_new(style->Family));
|
||||
pango_attr_list_insert(attrs,
|
||||
pango_attr_size_new((gint) (style->Size * PANGO_SCALE)));
|
||||
pango_attr_list_insert(attrs,
|
||||
pango_attr_weight_new(pangoWeights[style->Weight]));
|
||||
pango_attr_list_insert(attrs,
|
||||
pango_attr_style_new(pangoItalics[style->Italic]));
|
||||
if (style->SmallCaps)
|
||||
pango_attr_list_insert(attrs,
|
||||
pango_attr_variant_new(PANGO_VARIANT_SMALL_CAPS));
|
||||
pango_attr_list_insert(attrs,
|
||||
pango_attr_stretch_new(pangoStretches[style->Stretch]));
|
||||
cairo_set_source_rgba(c->cr, style->TextR, style->TextG, style->TextB, style->TextA);
|
||||
if (style->HasBackground) {
|
||||
// TODO
|
||||
}
|
||||
if (style->HasStrikethrough) {
|
||||
// TODO
|
||||
}
|
||||
if (style->HasUnderline) {
|
||||
// TODO
|
||||
}
|
||||
if (style->Language != NULL)
|
||||
pango_attr_list_insert(attrs,
|
||||
pango_attr_language_new(pango_language_from_string(style->Language)));
|
||||
layout = uiNew(uiDrawTextLayout);
|
||||
layout->s = g_strdup(text);
|
||||
|
||||
layout = pango_cairo_create_layout(c->cr);
|
||||
pango_layout_set_text(layout, text, -1);
|
||||
pango_layout_set_attributes(layout, attrs);
|
||||
cairo_move_to(c->cr, x, y);
|
||||
pango_cairo_show_layout(c->cr, layout);
|
||||
layout->desc = pango_font_description_new();
|
||||
pango_font_description_set_family(layout->desc,
|
||||
initialStyle->Family);
|
||||
pango_font_description_set_size(layout->desc,
|
||||
(gint) (initialStyle->Size * PANGO_SCALE));
|
||||
pango_font_description_set_weight(layout->desc,
|
||||
pangoWeights[initialStyle->Weight]);
|
||||
pango_font_description_set_style(layout->desc,
|
||||
pangoItalics[initialStyle->Italic]);
|
||||
variant = PANGO_VARIANT_NORMAL;
|
||||
if (initialStyle->SmallCaps)
|
||||
variant = PANGO_VARIANT_SMALL_CAPS;
|
||||
pango_font_description_set_variant(layout->desc, variant);
|
||||
pango_font_description_set_stretch(layout->desc,
|
||||
pangoStretches[initialStyle->Stretch]);
|
||||
pango_font_description_set_gravity(layout->desc,
|
||||
pangoGravities[initialStyle->Gravity]);
|
||||
|
||||
g_object_unref(layout);
|
||||
pango_attr_list_unref(attrs);
|
||||
return layout;
|
||||
}
|
||||
|
||||
void uiDrawFreeTextLayout(uiDrawTextLayout *layout)
|
||||
{
|
||||
pango_font_description_free(layout->desc);
|
||||
g_free(layout->s);
|
||||
uiFree(layout);
|
||||
}
|
||||
|
||||
void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout)
|
||||
{
|
||||
PangoLayout *pl;
|
||||
|
||||
pl = pango_cairo_create_layout(c->cr);
|
||||
pango_layout_set_text(pl, layout->s, -1);
|
||||
// this is safe; the description is copied
|
||||
pango_layout_set_font_description(pl, layout->desc);
|
||||
cairo_move_to(c->cr, x, y);
|
||||
pango_cairo_show_layout(c->cr, pl);
|
||||
g_object_unref(pl);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue