Removed the vertical forms attribute. This is a compatiblity nightmare.

This commit is contained in:
Pietro Gagliardi 2017-02-24 01:23:47 -05:00
parent e5f3646fcf
commit be56ec3626
14 changed files with 79 additions and 76 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,2 @@
case uiAttributeVerticalForms:
return boolsEqual(attr, spec);

View File

@ -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, ", ");

View File

@ -0,0 +1,2 @@
// TODO rename to uiAttributeVertical?
uiAttributeVerticalForms, // 0 = off, 1 = on

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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