Finished (almost) the uiAttribute stuff.

This commit is contained in:
Pietro Gagliardi 2018-08-18 17:13:47 -04:00
parent 9678e60dd6
commit 89353fffd3
1 changed files with 168 additions and 102 deletions

View File

@ -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