Removed the vertical forms attribute. This is a compatiblity nightmare.
This commit is contained in:
parent
e5f3646fcf
commit
be56ec3626
|
@ -0,0 +1,13 @@
|
|||
Proper vertical text support in uiDrawTextLayout was removed because DirectWrite doesn't add this until Windows 8.1 (unless I drop IDWriteTextLayout and do the script analysis myself; TODO consider this possibility).
|
||||
|
||||
On OS X, setting the vertical forms attribute stacks non-vertical scripts in vertical text (rotates each individual glyph) with Core Text, whereas everything else — including Cocoa's text system — rotates entire non-vertical strings. Not sure what to do about this except manually detect which characters to apply the attribute to:
|
||||
http://www.unicode.org/notes/tn22/RobustVerticalLayout.pdf
|
||||
http://www.unicode.org/Public/vertical/revision-17/VerticalOrientation-17.txt
|
||||
|
||||
In addition, with Core Text, the vertical forms attribute vertically centers the vertical glyphs on the bhorizontal baseline, rather than flush with the text. Using the baseline class attribute doesn't seem to work.
|
||||
|
||||
If readded, this will need to be a layout-wide setting, not a per-character setting. Pango works right this way; the current Pango code doesn't seem to work.
|
||||
|
||||
More links:
|
||||
https://www.w3.org/TR/2012/NOTE-jlreq-20120403/#line-composition
|
||||
https://www.w3.org/TR/REC-CSS2/notes.html
|
|
@ -0,0 +1,19 @@
|
|||
case uiAttributeVerticalForms:
|
||||
if (spec->Value != 0) {
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTVerticalFormsAttributeName, kCFBooleanTrue);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassRoman);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicCentered);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicLow);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicHigh);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassHanging);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassMath);
|
||||
} else {
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTVerticalFormsAttributeName, kCFBooleanFalse);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassRoman);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicCentered);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicLow);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicHigh);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassHanging);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassMath);
|
||||
}
|
||||
break;
|
|
@ -0,0 +1,9 @@
|
|||
PangoGravity gravity;
|
||||
|
||||
case uiAttributeVerticalForms:
|
||||
gravity = PANGO_GRAVITY_SOUTH;
|
||||
if (spec->Value != 0)
|
||||
gravity = PANGO_GRAVITY_EAST;
|
||||
addattr(p, start, end,
|
||||
pango_attr_gravity_new(gravity));
|
||||
break;
|
|
@ -0,0 +1,15 @@
|
|||
uint32_t vertval;
|
||||
|
||||
case uiAttributeVerticalForms:
|
||||
// LONGTERM 8 and/or 8.1 add other methods for vertical text
|
||||
op.p = p;
|
||||
op.start = start;
|
||||
op.end = end;
|
||||
vertval = 0;
|
||||
if (spec->Value != 0)
|
||||
vertval = 1;
|
||||
doOpenType("vert", vertval, &op);
|
||||
doOpenType("vrt2", vertval, &op);
|
||||
doOpenType("vkrn", vertval, &op);
|
||||
doOpenType("vrtr", vertval, &op);
|
||||
break;
|
|
@ -0,0 +1,2 @@
|
|||
case uiAttributeVerticalForms:
|
||||
return boolsEqual(attr, spec);
|
|
@ -0,0 +1,18 @@
|
|||
next = "vertical glyph forms";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeVerticalForms;
|
||||
spec.Value = 1;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, " (which you can draw rotated for proper vertical text; for instance, ");
|
||||
next = "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeVerticalForms;
|
||||
spec.Value = 1;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, ")");
|
||||
|
||||
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
|
@ -0,0 +1,2 @@
|
|||
// TODO rename to uiAttributeVertical?
|
||||
uiAttributeVerticalForms, // 0 = off, 1 = on
|
|
@ -342,11 +342,10 @@ static int specsIdentical(struct attr *attr, uiAttributeSpec *spec)
|
|||
attr->spec.G == spec->G &&
|
||||
attr->spec.B == spec->B &&
|
||||
attr->spec.A == spec->A;
|
||||
case uiAttributeVerticalForms:
|
||||
return boolsEqual(attr, spec);
|
||||
case uiAttributeLanguage:
|
||||
return asciiStringsEqualCaseFold((char *) (attr->spec.Value), (char *) (spec->Value));
|
||||
// TODO
|
||||
// TODO use boolsEqual() on boolean features
|
||||
}
|
||||
// handles the rest
|
||||
return attr->spec.Value == spec->Value;
|
||||
|
|
|
@ -219,25 +219,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
|||
[p->backgroundBlocks addObject:block];
|
||||
Block_release(block);
|
||||
break;
|
||||
case uiAttributeVerticalForms:
|
||||
if (spec->Value != 0) {
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTVerticalFormsAttributeName, kCFBooleanTrue);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassRoman);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicCentered);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicLow);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicHigh);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassHanging);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassMath);
|
||||
} else {
|
||||
CFAttributedStringSetAttribute(p->mas, range, kCTVerticalFormsAttributeName, kCFBooleanFalse);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassRoman);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicCentered);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicLow);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassIdeographicHigh);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassHanging);
|
||||
// CFAttributedStringSetAttribute(p->mas, range, kCTBaselineClassAttributeName, kCTBaselineClassMath);
|
||||
}
|
||||
break;
|
||||
case uiAttributeUnderline:
|
||||
switch (spec->Value) {
|
||||
case uiDrawUnderlineStyleNone:
|
||||
|
|
|
@ -93,25 +93,6 @@ static void setupAttributedString(void)
|
|||
|
||||
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
||||
|
||||
next = "vertical glyph forms";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeVerticalForms;
|
||||
spec.Value = 1;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, " (which you can draw rotated for proper vertical text; for instance, ");
|
||||
next = "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
uiAttributedStringAppendUnattributed(attrstr, next);
|
||||
spec.Type = uiAttributeVerticalForms;
|
||||
spec.Value = 1;
|
||||
uiAttributedStringSetAttribute(attrstr, &spec, start, end);
|
||||
uiAttributedStringAppendUnattributed(attrstr, ")");
|
||||
|
||||
uiAttributedStringAppendUnattributed(attrstr, ", ");
|
||||
|
||||
next = "multiple";
|
||||
start = uiAttributedStringLen(attrstr);
|
||||
end = start + strlen(next);
|
||||
|
|
|
@ -1,18 +1,6 @@
|
|||
// 17 january 2017
|
||||
#include "drawtext.h"
|
||||
|
||||
// okay everything is definitely bugged in the OS X code
|
||||
// - occasional segfaults on startup
|
||||
// - very rare size attributes in the attributed string example don't terminate for a while, making everything big
|
||||
// - very very rare trace/bpt faults on startup
|
||||
/*
|
||||
objc[14827]: autorelease pool page 0x7feeab88b000 corrupted
|
||||
magic 0xe000007f 0xeea9f2df 0x0000007f 0xeea9f2e0
|
||||
should be 0xa1a1a1a1 0x4f545541 0x454c4552 0x21455341
|
||||
pthread 0x0
|
||||
should be 0x7fff727a1000
|
||||
*/
|
||||
|
||||
static uiWindow *mainwin;
|
||||
static uiBox *box;
|
||||
static uiCombobox *exampleList;
|
||||
|
|
|
@ -10,8 +10,6 @@ _UI_ENUM(uiAttribute) {
|
|||
uiAttributeStretch,
|
||||
uiAttributeColor, // use R, G, B, A
|
||||
uiAttributeBackground, // use R, G, B, A
|
||||
// TODO rename to uiAttributeVertical?
|
||||
uiAttributeVerticalForms, // 0 = off, 1 = on
|
||||
|
||||
// TODO kerning amount
|
||||
// OS X: kCTKernAttributeName
|
||||
|
|
|
@ -141,7 +141,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
|||
{
|
||||
struct foreachParams *p = (struct foreachParams *) data;
|
||||
GClosure *closure;
|
||||
PangoGravity gravity;
|
||||
PangoUnderline underline;
|
||||
PangoLanguage *lang;
|
||||
struct otParam op;
|
||||
|
@ -183,13 +182,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
|||
spec->R, spec->G, spec->B, spec->A);
|
||||
g_ptr_array_add(p->backgroundClosures, closure);
|
||||
break;
|
||||
case uiAttributeVerticalForms:
|
||||
gravity = PANGO_GRAVITY_SOUTH;
|
||||
if (spec->Value != 0)
|
||||
gravity = PANGO_GRAVITY_EAST;
|
||||
addattr(p, start, end,
|
||||
pango_attr_gravity_new(gravity));
|
||||
break;
|
||||
case uiAttributeUnderline:
|
||||
switch (spec->Value) {
|
||||
case uiDrawUnderlineStyleNone:
|
||||
|
|
|
@ -112,7 +112,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
|||
WCHAR *wfamily;
|
||||
size_t ostart, oend;
|
||||
BOOL hasUnderline;
|
||||
uint32_t vertval;
|
||||
WCHAR *localeName;
|
||||
struct otParam op;
|
||||
HRESULT hr;
|
||||
|
@ -176,19 +175,6 @@ static int processAttribute(uiAttributedString *s, uiAttributeSpec *spec, size_t
|
|||
mkBackgroundFunc(ostart, oend,
|
||||
spec->R, spec->G, spec->B, spec->A));
|
||||
break;
|
||||
case uiAttributeVerticalForms:
|
||||
// LONGTERM 8 and/or 8.1 add other methods for vertical text
|
||||
op.p = p;
|
||||
op.start = start;
|
||||
op.end = end;
|
||||
vertval = 0;
|
||||
if (spec->Value != 0)
|
||||
vertval = 1;
|
||||
doOpenType("vert", vertval, &op);
|
||||
doOpenType("vrt2", vertval, &op);
|
||||
doOpenType("vkrn", vertval, &op);
|
||||
doOpenType("vrtr", vertval, &op);
|
||||
break;
|
||||
case uiAttributeUnderline:
|
||||
ensureEffectsInRange(p, start, end, [=](textDrawingEffect *t) {
|
||||
t->hasUnderline = true;
|
||||
|
|
Loading…
Reference in New Issue