diff --git a/docs/text.coffee.md b/docs/text.coffee.md index f9cecd7..28998f9 100644 --- a/docs/text.coffee.md +++ b/docs/text.coffee.md @@ -91,6 +91,8 @@ below. * `link` - a URL to link this text to (shortcut to create an annotation) * `underline` - whether to underline the text * `strike` - whether to strike out the text +* `oblique` - whether to slant the text (angle in degrees or `true`) +* `baseline` - the vertical alignment of the text with respect to its insertion point (values as [canvas textBaseline](https://www.w3schools.com/tags/canvas_textbaseline.asp)) * `continued` - whether the text segment will be followed immediately by another segment. Useful for changing styling in the middle of a paragraph. * `features` - an array of [OpenType feature tags](https://www.microsoft.com/typography/otspec/featuretags.htm) to apply. If not provided, a set of defaults is used. diff --git a/lib/font/afm.coffee b/lib/font/afm.coffee index 4e6c074..62ecb3d 100644 --- a/lib/font/afm.coffee +++ b/lib/font/afm.coffee @@ -16,6 +16,8 @@ class AFMFont @bbox = (+e for e in @attributes['FontBBox'].split /\s+/) @ascender = +(@attributes['Ascender'] or 0) @descender = +(@attributes['Descender'] or 0) + @xHeight = +(@attributes['XHeight'] or 0) + @capHeight = +(@attributes['CapHeight'] or 0) @lineGap = (@bbox[3] - @bbox[1]) - (@ascender - @descender) parse: -> @@ -192,4 +194,4 @@ class AFMFont udieresis yacute thorn ydieresis '''.split(/\s+/) -module.exports = AFMFont \ No newline at end of file +module.exports = AFMFont diff --git a/lib/font/embedded.coffee b/lib/font/embedded.coffee index f374e3c..7a65e1b 100644 --- a/lib/font/embedded.coffee +++ b/lib/font/embedded.coffee @@ -11,6 +11,8 @@ class EmbeddedFont extends PDFFont @scale = 1000 / @font.unitsPerEm @ascender = @font.ascent * @scale @descender = @font.descent * @scale + @xHeight = @font.xHeight * @scale + @capHeight = @font.capHeight * @scale @lineGap = @font.lineGap * @scale @bbox = @font.bbox diff --git a/lib/font/standard.coffee b/lib/font/standard.coffee index 95983ce..5301190 100644 --- a/lib/font/standard.coffee +++ b/lib/font/standard.coffee @@ -5,7 +5,7 @@ fs = require 'fs' class StandardFont extends PDFFont constructor: (@document, @name, @id) -> @font = new AFMFont STANDARD_FONTS[@name]() - {@ascender,@descender,@bbox,@lineGap} = @font + {@ascender,@descender,@bbox,@lineGap,@xHeight,@capHeight} = @font embed: -> @dictionary.data = diff --git a/lib/mixins/text.coffee b/lib/mixins/text.coffee index af3adc1..7d564bb 100644 --- a/lib/mixins/text.coffee +++ b/lib/mixins/text.coffee @@ -207,6 +207,29 @@ module.exports = spaceWidth = @widthOfString(' ') + characterSpacing wordSpacing = Math.max 0, (options.lineWidth - textWidth) / Math.max(1, words.length - 1) - spaceWidth + # text baseline alignments based on http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling + if typeof options.baseline is 'number' + dy = -options.baseline + else + switch options.baseline + when 'svg-middle' + dy = 0.5 * @_font.xHeight + when 'middle', 'svg-central' + dy = 0.5 * (@_font.descender + @_font.ascender) + when 'bottom', 'ideographic' + dy = @_font.descender + when 'alphabetic' + dy = 0; + when 'mathematical' + dy = 0.5 * @_font.ascender + when 'hanging' + dy = 0.8 * @_font.ascender + when 'top' + dy = @_font.ascender + else + dy = @_font.ascender + dy = dy / 1000 * @_fontSize + # calculate the actual rendered width of the string after word and character spacing renderedWidth = options.textWidth + (wordSpacing * (options.wordCount - 1)) + (characterSpacing * (text.length - 1)) @@ -231,10 +254,21 @@ module.exports = @stroke() @restore() - # flip coordinate system @save() + + # oblique (angle in degrees or boolean) + if options.oblique + if typeof options.oblique is 'number' + skew = -Math.tan(options.oblique * Math.PI / 180) + else + skew = -0.25 + @transform 1, 0, 0, 1, x, y + @transform 1, 0, skew, 1, -skew * dy, 0 + @transform 1, 0, 0, 1, -x, -y + + # flip coordinate system @transform 1, 0, 0, -1, 0, @page.height - y = @page.height - y - (@_font.ascender / 1000 * @_fontSize) + y = @page.height - y - dy # add current font to page if necessary @page.fonts[@_font.id] ?= @_font.ref()