Finished (almost) the uiAttribute stuff.
This commit is contained in:
parent
9678e60dd6
commit
89353fffd3
270
drawtext.go
270
drawtext.go
|
@ -2,7 +2,33 @@
|
||||||
|
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
|
// #include <stdlib.h>
|
||||||
// #include "ui.h"
|
// #include "ui.h"
|
||||||
|
// #include "util.h"
|
||||||
|
// typedef struct pkguiCColor pkguiCColor;
|
||||||
|
// struct pkguiCColor { double *r; double *g; double *b; double *a; };
|
||||||
|
// static inline pkguiCColor pkguiNewCColor(void)
|
||||||
|
// {
|
||||||
|
// pkguiCColor c;
|
||||||
|
//
|
||||||
|
// c.r = (double *) pkguiAlloc(4 * sizeof (double));
|
||||||
|
// c.g = c.r + 1;
|
||||||
|
// c.b = c.g + 1;
|
||||||
|
// c.a = c.b + 1;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
// static inline void pkguiFreeCColor(pkguiCColor c)
|
||||||
|
// {
|
||||||
|
// free(c.r);
|
||||||
|
// }
|
||||||
|
// static inline uiUnderlineColor *pkguiNewUnderlineColor(void)
|
||||||
|
// {
|
||||||
|
// return (uiUnderlineColor *) pkguiAlloc(sizeof (uiUnderlineColor));
|
||||||
|
// }
|
||||||
|
// static inline void pkguiFreeUnderlineColor(uiUnderlineColor *c)
|
||||||
|
// {
|
||||||
|
// free(c);
|
||||||
|
// }
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
// Attribute stores information about an attribute in an
|
// Attribute stores information about an attribute in an
|
||||||
|
@ -19,6 +45,7 @@ import "C"
|
||||||
// - TextBackground
|
// - TextBackground
|
||||||
// - Underline
|
// - Underline
|
||||||
// - UnderlineColor
|
// - UnderlineColor
|
||||||
|
// - UnderlineColorCustom
|
||||||
// - OpenTypeFeatures
|
// - OpenTypeFeatures
|
||||||
//
|
//
|
||||||
// For every Unicode codepoint in the AttributedString, at most one
|
// For every Unicode codepoint in the AttributedString, at most one
|
||||||
|
@ -62,19 +89,19 @@ func (s TextSize) toLibui() *C.uiAttribute {
|
||||||
// TextWeightBlack.
|
// TextWeightBlack.
|
||||||
type TextWeight int
|
type TextWeight int
|
||||||
const (
|
const (
|
||||||
TextWeightMinimum = 0,
|
TextWeightMinimum TextWeight = 0
|
||||||
TextWeightThin = 100,
|
TextWeightThin TextWeight = 100
|
||||||
TextWeightUltraLight = 200,
|
TextWeightUltraLight TextWeight = 200
|
||||||
TextWeightLight = 300,
|
TextWeightLight TextWeight = 300
|
||||||
TextWeightBook = 350,
|
TextWeightBook TextWeight = 350
|
||||||
TextWeightNormal = 400,
|
TextWeightNormal TextWeight = 400
|
||||||
TextWeightMedium = 500,
|
TextWeightMedium TextWeight = 500
|
||||||
TextWeightSemiBold = 600,
|
TextWeightSemiBold TextWeight = 600
|
||||||
TextWeightBold = 700,
|
TextWeightBold TextWeight = 700
|
||||||
TextWeightUltraBold = 800,
|
TextWeightUltraBold TextWeight = 800
|
||||||
TextWeightHeavy = 900,
|
TextWeightHeavy TextWeight = 900
|
||||||
TextWeightUltraHeavy = 950,
|
TextWeightUltraHeavy TextWeight = 950
|
||||||
TextWeightMaximum = 1000,
|
TextWeightMaximum TextWeight = 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w TextWeight) toLibui() *C.uiAttribute {
|
func (w TextWeight) toLibui() *C.uiAttribute {
|
||||||
|
@ -164,46 +191,49 @@ func (u Underline) toLibui() *C.uiAttribute {
|
||||||
return C.uiNewUnderlineAttribute(C.uiUnderline(u))
|
return C.uiNewUnderlineAttribute(C.uiUnderline(u))
|
||||||
}
|
}
|
||||||
|
|
||||||
////////// TODOTODO
|
// UnderlineColor is an Attribute that changes the color of any
|
||||||
|
// underline on the text it is applied to, regardless of the type of
|
||||||
// uiUnderlineColor specifies the color of any underline on the text it
|
// underline. In addition to being able to specify the
|
||||||
// is applied to, regardless of the type of underline. In addition to
|
// platform-specific colors for suggestion underlines here, you can
|
||||||
// being able to specify a custom color, you can explicitly specify
|
// also use a custom color with UnderlineColorCustom.
|
||||||
// platform-specific colors for suggestion underlines; to use them
|
//
|
||||||
// correctly, pair them with uiUnderlineSuggestion (though they can
|
// To use the constants here correctly, pair them with
|
||||||
// be used on other types of underline as well).
|
// UnderlineSuggestion (though they can be used on other types of
|
||||||
|
// underline as well).
|
||||||
//
|
//
|
||||||
// If an underline type is applied but no underline color is
|
// If an underline type is applied but no underline color is
|
||||||
// specified, the text color is used instead. If an underline color
|
// specified, the text color is used instead. If an underline color
|
||||||
// is specified without an underline type, the underline color
|
// is specified without an underline type, the underline color
|
||||||
// attribute is ignored, but not removed from the uiAttributedString.
|
// attribute is ignored, but not removed from the uiAttributedString.
|
||||||
_UI_ENUM(uiUnderlineColor) {
|
type UnderlineColor int
|
||||||
uiUnderlineColorCustom,
|
const (
|
||||||
uiUnderlineColorSpelling,
|
UnderlineColorSpelling UnderlineColor = iota + 1
|
||||||
uiUnderlineColorGrammar,
|
UnderlineColorGrammar
|
||||||
uiUnderlineColorAuxiliary, // for instance, the color used by smart replacements on macOS or in Microsoft Office
|
UnderlineColorAuxiliary // for instance, the color used by smart replacements on macOS or in Microsoft Office
|
||||||
};
|
)
|
||||||
|
|
||||||
// uiNewUnderlineColorAttribute() creates a new uiAttribute that
|
func (u UnderlineColor) toLibui() *C.uiAttribute {
|
||||||
// changes the color of the underline on the text it is applied to.
|
return C.uiNewUnderlineColorAttribute(C.uiUnderlineColor(u), 0, 0, 0, 0)
|
||||||
// It is an error to specify an underline color not specified in
|
}
|
||||||
// uiUnderlineColor.
|
|
||||||
//
|
|
||||||
// If the specified color type is uiUnderlineColorCustom, it is an
|
|
||||||
// error to specify an invalid color value. Otherwise, the color values
|
|
||||||
// are ignored and should be specified as zero.
|
|
||||||
_UI_EXTERN uiAttribute *uiNewUnderlineColorAttribute(uiUnderlineColor u, double r, double g, double b, double a);
|
|
||||||
|
|
||||||
// uiAttributeUnderlineColor() returns the underline color stored in
|
// UnderlineColorCustom is an Attribute like UnderlineColor, except
|
||||||
// a. It is an error to call this on a uiAttribute that does not hold an
|
// it allows specifying a custom color.
|
||||||
// underline color.
|
type UnderlineColorCustom struct {
|
||||||
_UI_EXTERN void uiAttributeUnderlineColor(const uiAttribute *a, uiUnderlineColor *u, double *r, double *g, double *b, double *alpha);
|
R float64
|
||||||
|
G float64
|
||||||
|
B float64
|
||||||
|
A float64
|
||||||
|
}
|
||||||
|
|
||||||
// uiOpenTypeFeatures represents a set of OpenType feature
|
func (u UnderlineColorCustom) toLibui() *C.uiAttribute {
|
||||||
// tag-value pairs, for applying OpenType features to text.
|
return C.uiNewUnderlineColorAttribute(C.uiUnderlineColorCustom, C.double(u.R), C.double(u.G), C.double(u.B), C.double(u.A))
|
||||||
// OpenType feature tags are four-character codes defined by
|
}
|
||||||
// OpenType that cover things from design features like small
|
|
||||||
// caps and swashes to language-specific glyph shapes and
|
// OpenTypeFeatures is an Attribute that represents a set of
|
||||||
|
// OpenType feature tag-value pairs, for applying OpenType
|
||||||
|
// features to text. OpenType feature tags are four-character codes
|
||||||
|
// defined by OpenType that cover things from design features like
|
||||||
|
// small caps and swashes to language-specific glyph shapes and
|
||||||
// beyond. Each tag may only appear once in any given
|
// beyond. Each tag may only appear once in any given
|
||||||
// uiOpenTypeFeatures instance. Each value is a 32-bit integer,
|
// uiOpenTypeFeatures instance. Each value is a 32-bit integer,
|
||||||
// often used as a Boolean flag, but sometimes as an index to choose
|
// often used as a Boolean flag, but sometimes as an index to choose
|
||||||
|
@ -217,67 +247,103 @@ _UI_EXTERN void uiAttributeUnderlineColor(const uiAttribute *a, uiUnderlineColor
|
||||||
// for the complete list of available features, information on specific
|
// for the complete list of available features, information on specific
|
||||||
// features, and how to use them.
|
// features, and how to use them.
|
||||||
// TODO invalid features
|
// TODO invalid features
|
||||||
typedef struct uiOpenTypeFeatures uiOpenTypeFeatures;
|
|
||||||
|
|
||||||
// uiOpenTypeFeaturesForEachFunc is the type of the function
|
|
||||||
// invoked by uiOpenTypeFeaturesForEach() for every OpenType
|
|
||||||
// feature in otf. Refer to that function's documentation for more
|
|
||||||
// details.
|
|
||||||
typedef uiForEach (*uiOpenTypeFeaturesForEachFunc)(const uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value, void *data);
|
|
||||||
|
|
||||||
// @role uiOpenTypeFeatures constructor
|
|
||||||
// uiNewOpenTypeFeatures() returns a new uiOpenTypeFeatures
|
|
||||||
// instance, with no tags yet added.
|
|
||||||
_UI_EXTERN uiOpenTypeFeatures *uiNewOpenTypeFeatures(void);
|
|
||||||
|
|
||||||
// @role uiOpenTypeFeatures destructor
|
|
||||||
// uiFreeOpenTypeFeatures() frees otf.
|
|
||||||
_UI_EXTERN void uiFreeOpenTypeFeatures(uiOpenTypeFeatures *otf);
|
|
||||||
|
|
||||||
// uiOpenTypeFeaturesClone() makes a copy of otf and returns it.
|
|
||||||
// Changing one will not affect the other.
|
|
||||||
_UI_EXTERN uiOpenTypeFeatures *uiOpenTypeFeaturesClone(const uiOpenTypeFeatures *otf);
|
|
||||||
|
|
||||||
// uiOpenTypeFeaturesAdd() adds the given feature tag and value
|
|
||||||
// to otf. The feature tag is specified by a, b, c, and d. If there is
|
|
||||||
// already a value associated with the specified tag in otf, the old
|
|
||||||
// value is removed.
|
|
||||||
_UI_EXTERN void uiOpenTypeFeaturesAdd(uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value);
|
|
||||||
|
|
||||||
// uiOpenTypeFeaturesRemove() removes the given feature tag
|
|
||||||
// and value from otf. If the tag is not present in otf,
|
|
||||||
// uiOpenTypeFeaturesRemove() does nothing.
|
|
||||||
_UI_EXTERN void uiOpenTypeFeaturesRemove(uiOpenTypeFeatures *otf, char a, char b, char c, char d);
|
|
||||||
|
|
||||||
// uiOpenTypeFeaturesGet() determines whether the given feature
|
|
||||||
// tag is present in otf. If it is, *value is set to the tag's value and
|
|
||||||
// nonzero is returned. Otherwise, zero is returned.
|
|
||||||
//
|
//
|
||||||
// Note that if uiOpenTypeFeaturesGet() returns zero, value isn't
|
// Note that if a feature is not present in a OpenTypeFeatures,
|
||||||
// changed. This is important: if a feature is not present in a
|
// the feature is NOT treated as if its value was zero, unlike in Go.
|
||||||
// uiOpenTypeFeatures, the feature is NOT treated as if its
|
// Script-specific font shaping rules and font-specific feature
|
||||||
// value was zero anyway. Script-specific font shaping rules and
|
// settings may use a different default value for a feature. You
|
||||||
// font-specific feature settings may use a different default value
|
// should likewise NOT treat a missing feature as having a value of
|
||||||
// for a feature. You should likewise not treat a missing feature as
|
// zero either. Instead, a missing feature should be treated as
|
||||||
// having a value of zero either. Instead, a missing feature should
|
// having some unspecified default value.
|
||||||
// be treated as having some unspecified default value.
|
//
|
||||||
_UI_EXTERN int uiOpenTypeFeaturesGet(const uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t *value);
|
// Note that despite OpenTypeFeatures being a map, its contents
|
||||||
|
// are copied by AttributedString. Modifying an OpenTypeFeatures
|
||||||
|
// after giving it to an AttributedString, or modifying one that comes
|
||||||
|
// out of an AttributedString, will have no effect.
|
||||||
|
type OpenTypeFeatures map[OpenTypeTag]uint32
|
||||||
|
|
||||||
// uiOpenTypeFeaturesForEach() executes f for every tag-value
|
func (o OpenTypeFeatures) toLibui() *C.uiAttribute {
|
||||||
// pair in otf. The enumeration order is unspecified. You cannot
|
otf := C.uiNewOpenTypeFeatures()
|
||||||
// modify otf while uiOpenTypeFeaturesForEach() is running.
|
defer C.uiFreeOpenTypeFeatures(otf)
|
||||||
_UI_EXTERN void uiOpenTypeFeaturesForEach(const uiOpenTypeFeatures *otf, uiOpenTypeFeaturesForEachFunc f, void *data);
|
for tag, value := range o {
|
||||||
|
a := byte((tag >> 24) & 0xFF)
|
||||||
|
b := byte((tag >> 16) & 0xFF)
|
||||||
|
c := byte((tag >> 8) & 0xFF)
|
||||||
|
d := byte(tag & 0xFF)
|
||||||
|
C.uiOpenTypeFeaturesAdd(otf, C.char(a), C.char(b), C.char(c), C.char(d), C.uint32_t(value))
|
||||||
|
}
|
||||||
|
return C.uiNewFeaturesAttribute(otf)
|
||||||
|
}
|
||||||
|
|
||||||
// uiNewFeaturesAttribute() creates a new uiAttribute that changes
|
// OpenTypeTag represents a four-byte OpenType feature tag.
|
||||||
// the font family of the text it is applied to. otf is copied; you may
|
type OpenTypeTag uint32
|
||||||
// free it after uiNewFeaturesAttribute() returns.
|
|
||||||
_UI_EXTERN uiAttribute *uiNewFeaturesAttribute(const uiOpenTypeFeatures *otf);
|
|
||||||
|
|
||||||
// uiAttributeFeatures() returns the OpenType features stored in a.
|
// ToOpenTypeTag converts the four characters a, b, c, and d into
|
||||||
// The returned uiOpenTypeFeatures object is owned by a. It is an
|
// an OpenTypeTag.
|
||||||
// error to call this on a uiAttribute that does not hold OpenType
|
func ToOpenTypeTag(a, b, c, d byte) OpenTypeTag {
|
||||||
// features.
|
return (uint32(a) << 24) |
|
||||||
_UI_EXTERN const uiOpenTypeFeatures *uiAttributeFeatures(const uiAttribute *a);
|
(uint32(b) << 16) |
|
||||||
|
(uint32(c) << 8) |
|
||||||
|
uint32(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func attributeFromLibui(a *C.uiAttribute) Attribute {
|
||||||
|
switch C.uiAttributeGetType(a) {
|
||||||
|
case C.uiAttributeTypeFamily:
|
||||||
|
cf := C.uiAttributeFamily(a)
|
||||||
|
return TextFamily(C.GoString(cf))
|
||||||
|
case C.uiAttributeTypeSize:
|
||||||
|
return TextSize(C.uiAttributeSize(a))
|
||||||
|
case C.uiAttributeTypeWeight:
|
||||||
|
return TextWeight(C.uiAttributeWeight(a))
|
||||||
|
case C.uiAttributeTypeItalic:
|
||||||
|
return TextItalic(C.uiAttributeItalic(a))
|
||||||
|
case C.uiAttributeTypeStretch:
|
||||||
|
return TextStretch(C.uiAttributeStretch(a))
|
||||||
|
case C.uiAttributeTypeColor:
|
||||||
|
cc := C.pkguiNewCColor()
|
||||||
|
defer C.pkguiFreeCColor(cc)
|
||||||
|
C.uiAttributeColor(a, c.r, c.g, c.b, c.a)
|
||||||
|
return TextColor{
|
||||||
|
R: float64(*(c.r)),
|
||||||
|
G: float64(*(c.g)),
|
||||||
|
B: float64(*(c.b)),
|
||||||
|
A: float64(*(c.a)),
|
||||||
|
}
|
||||||
|
case C.uiAttributeTypeBackground:
|
||||||
|
cc := C.pkguiNewCColor()
|
||||||
|
defer C.pkguiFreeCColor(cc)
|
||||||
|
C.uiAttributeColor(a, c.r, c.g, c.b, c.a)
|
||||||
|
return TextBackground{
|
||||||
|
R: float64(*(c.r)),
|
||||||
|
G: float64(*(c.g)),
|
||||||
|
B: float64(*(c.b)),
|
||||||
|
A: float64(*(c.a)),
|
||||||
|
}
|
||||||
|
case C.uiAttributeTypeUnderline:
|
||||||
|
return Underline(C.uiAttributeUnderline(a))
|
||||||
|
case C.uiAttributeTypeUnderlineColor:
|
||||||
|
cu := C.pkguiNewUnderlineColor()
|
||||||
|
defer C.pkguiFreeUnderlineColor(cu)
|
||||||
|
cc := C.pkguiNewCColor()
|
||||||
|
defer C.pkguiFreeCColor(cc)
|
||||||
|
C.uiAttributeUnderlineColor(a, cu, c.r, c.g, c.b, c.a)
|
||||||
|
if *cu == C.uiAttributeUnderlineColorCustom {
|
||||||
|
return UnderlineColorCustom{
|
||||||
|
R: float64(*(c.r)),
|
||||||
|
G: float64(*(c.g)),
|
||||||
|
B: float64(*(c.b)),
|
||||||
|
A: float64(*(c.a)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UnderlineColor(*cu)
|
||||||
|
case C.uiAttributeTypeFeatures:
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
///////// TODOTODO
|
||||||
|
|
||||||
// uiAttributedString represents a string of UTF-8 text that can
|
// uiAttributedString represents a string of UTF-8 text that can
|
||||||
// optionally be embellished with formatting attributes. libui
|
// optionally be embellished with formatting attributes. libui
|
||||||
|
|
Loading…
Reference in New Issue