mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
New: implement baseline offsets and superscript/subscript support
This commit is contained in:
@@ -464,6 +464,22 @@ following:
|
||||
return _CPRealFontSize(_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the font size. Cocoa/AppKit compatibility alias for -size.
|
||||
*/
|
||||
- (float)pointSize
|
||||
{
|
||||
return [self size];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the font name. Cocoa/AppKit compatibility alias for -familyName.
|
||||
*/
|
||||
- (CPString)fontName
|
||||
{
|
||||
return [self familyName];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the font as a CSS string
|
||||
*/
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
@import "CPFont.j"
|
||||
|
||||
@global _MakeRangeFromAbs
|
||||
|
||||
@global document
|
||||
@global CPBaselineOffsetAttributeName
|
||||
@global CPSuperscriptAttributeName
|
||||
|
||||
@class CPTextContainer
|
||||
@class CPTextView
|
||||
@@ -1225,7 +1226,7 @@ var _objectsInRange = function(aList, aRange)
|
||||
if (![attributes objectForKey:_CPAttachmentInvisible])
|
||||
{
|
||||
var view = [attributes objectForKey:_CPAttachmentView];
|
||||
var run = {_range:CPMakeRangeCopy(effectiveRange), color:nil, font:nil, elem:nil, string:nil, view:view, paragraphStyle:paragraphStyle};
|
||||
var run = {_range:CPMakeRangeCopy(effectiveRange), color:nil, font:nil, elem:nil, string:nil, view:view, paragraphStyle:paragraphStyle, underline:underline, baselineOffset:0.0};
|
||||
_runs.push(run);
|
||||
}
|
||||
}
|
||||
@@ -1235,6 +1236,34 @@ var _objectsInRange = function(aList, aRange)
|
||||
bgcolor = [attributes objectForKey:CPBackgroundColorAttributeName],
|
||||
font = [attributes objectForKey:CPFontAttributeName] || [textStorage font] || [CPFont systemFontOfSize:12.0];
|
||||
|
||||
var baselineOffset = [attributes objectForKey:CPBaselineOffsetAttributeName],
|
||||
superscript = [attributes objectForKey:CPSuperscriptAttributeName];
|
||||
|
||||
if (baselineOffset === nil || baselineOffset === undefined || typeof baselineOffset !== "number")
|
||||
baselineOffset = 0.0;
|
||||
|
||||
if (superscript === nil || superscript === undefined || typeof superscript !== "number")
|
||||
superscript = 0;
|
||||
|
||||
if (superscript !== 0)
|
||||
{
|
||||
var size = [font size],
|
||||
scaledSize = size * 0.65,
|
||||
fontName = [font familyName],
|
||||
isBold = [font isBold],
|
||||
isItalic = [font isItalic];
|
||||
|
||||
font = [CPFont _fontWithName:fontName size:scaledSize bold:isBold italic:isItalic];
|
||||
|
||||
if (baselineOffset === 0.0)
|
||||
{
|
||||
if (superscript > 0)
|
||||
baselineOffset = size * 0.35;
|
||||
else
|
||||
baselineOffset = -size * 0.15;
|
||||
}
|
||||
}
|
||||
|
||||
var currentLoc = effectiveRange.location,
|
||||
strLen = string.length,
|
||||
startIdx = 0;
|
||||
@@ -1254,7 +1283,9 @@ var _objectsInRange = function(aList, aRange)
|
||||
elem: nil,
|
||||
string: subString,
|
||||
bgcolor: bgcolor,
|
||||
paragraphStyle: paragraphStyle
|
||||
paragraphStyle: paragraphStyle,
|
||||
underline: underline,
|
||||
baselineOffset: baselineOffset
|
||||
};
|
||||
_runs.push(run);
|
||||
}
|
||||
@@ -1267,7 +1298,9 @@ var _objectsInRange = function(aList, aRange)
|
||||
elem: nil,
|
||||
string: nil,
|
||||
bgcolor: nil,
|
||||
paragraphStyle: paragraphStyle
|
||||
paragraphStyle: paragraphStyle,
|
||||
underline: underline,
|
||||
baselineOffset: 0.0
|
||||
};
|
||||
_runs.push(tabRun);
|
||||
|
||||
@@ -1286,7 +1319,9 @@ var _objectsInRange = function(aList, aRange)
|
||||
elem: nil,
|
||||
string: subString,
|
||||
bgcolor: bgcolor,
|
||||
paragraphStyle: paragraphStyle
|
||||
paragraphStyle: paragraphStyle,
|
||||
underline: underline,
|
||||
baselineOffset: baselineOffset
|
||||
};
|
||||
_runs.push(run);
|
||||
}
|
||||
@@ -1458,7 +1493,10 @@ var _objectsInRange = function(aList, aRange)
|
||||
if (!_RectEqualToRectHorizontally(newLineFragment._fragmentRect, _fragmentRect))
|
||||
return NO;
|
||||
|
||||
if (newFragmentRuns[i].color !== oldFragmentRuns[i].color || newFragmentRuns[i].bgcolor !== oldFragmentRuns[i].bgcolor || newFragmentRuns[i].font !== oldFragmentRuns[i].font)
|
||||
if (newFragmentRuns[i].color !== oldFragmentRuns[i].color ||
|
||||
newFragmentRuns[i].bgcolor !== oldFragmentRuns[i].bgcolor ||
|
||||
newFragmentRuns[i].font !== oldFragmentRuns[i].font ||
|
||||
newFragmentRuns[i].baselineOffset !== oldFragmentRuns[i].baselineOffset)
|
||||
return NO;
|
||||
|
||||
var oldStyle = oldFragmentRuns[i].paragraphStyle || [CPParagraphStyle defaultParagraphStyle],
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
@import "CPTextStorage.j"
|
||||
@import "CPFont.j"
|
||||
|
||||
@global CPBaselineOffsetAttributeName
|
||||
@global CPSuperscriptAttributeName
|
||||
|
||||
// forward declare these classes for type matching
|
||||
@class CPLayoutManager
|
||||
@class CPTextContainer
|
||||
@@ -353,9 +356,41 @@ var CPSystemTypesetterFactory,
|
||||
if (!currentFont)
|
||||
currentFont = [_textStorage font] || [CPFont systemFontOfSize:12.0];
|
||||
|
||||
ascent = [currentFont ascender];
|
||||
descent = [currentFont descender];
|
||||
leading = (ascent - descent) * 0.2; // FAKE leading
|
||||
// Safely retrieve and validate CPBaselineOffsetAttributeName
|
||||
var baselineOffset = [_currentAttributes objectForKey:CPBaselineOffsetAttributeName];
|
||||
if (baselineOffset === nil || baselineOffset === undefined || typeof baselineOffset !== "number")
|
||||
baselineOffset = 0.0;
|
||||
|
||||
// Safely retrieve and validate CPSuperscriptAttributeName
|
||||
var superscript = [_currentAttributes objectForKey:CPSuperscriptAttributeName];
|
||||
if (superscript === nil || superscript === undefined || typeof superscript !== "number")
|
||||
superscript = 0;
|
||||
|
||||
if (superscript !== 0)
|
||||
{
|
||||
var size = [currentFont size],
|
||||
scaledSize = size * 0.65,
|
||||
fontName = [currentFont familyName],
|
||||
isBold = [currentFont isBold],
|
||||
isItalic = [currentFont isItalic];
|
||||
|
||||
currentFont = [CPFont _fontWithName:fontName size:scaledSize bold:isBold italic:isItalic];
|
||||
|
||||
if (baselineOffset === 0.0)
|
||||
{
|
||||
if (superscript > 0)
|
||||
baselineOffset = size * 0.35;
|
||||
else
|
||||
baselineOffset = -size * 0.15;
|
||||
}
|
||||
}
|
||||
|
||||
var fontAscent = [currentFont ascender] || 0.0,
|
||||
fontDescent = [currentFont descender] || 0.0;
|
||||
|
||||
ascent = fontAscent + baselineOffset;
|
||||
descent = fontDescent + baselineOffset;
|
||||
leading = (fontAscent - fontDescent) * 0.2; // FAKE leading
|
||||
|
||||
currentFontLineHeight = ascent - descent + leading;
|
||||
|
||||
@@ -368,11 +403,15 @@ var CPSystemTypesetterFactory,
|
||||
|
||||
}
|
||||
|
||||
if (currentFontLineHeight > _lineHeight)
|
||||
_lineHeight = currentFontLineHeight;
|
||||
// Clean bounds logic to prevent NaN and layout calculation overhead
|
||||
var currentAscent = (ascent === undefined || isNaN(ascent)) ? 0.0 : ascent,
|
||||
currentLineHeight = (currentFontLineHeight === undefined || isNaN(currentFontLineHeight)) ? 12.0 : currentFontLineHeight;
|
||||
|
||||
if (ascent > _lineBase)
|
||||
_lineBase = ascent;
|
||||
if (currentLineHeight > _lineHeight)
|
||||
_lineHeight = currentLineHeight;
|
||||
|
||||
if (currentAscent > _lineBase)
|
||||
_lineBase = currentAscent;
|
||||
|
||||
lineRange.length++;
|
||||
measuringRange.length++;
|
||||
@@ -546,7 +585,7 @@ var CPSystemTypesetterFactory,
|
||||
isNewline = NO;
|
||||
_lineFragments = [];
|
||||
_lineHeight = 0;
|
||||
_lineBase = ascent;
|
||||
_lineBase = 0;
|
||||
isStartOfPhysicalLine = YES;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user