From 5ac614f802536ca524319ec836b39a8990eee8d8 Mon Sep 17 00:00:00 2001 From: R?my Oudompheng Date: Fri, 25 Oct 2013 11:00:02 +1100 Subject: [PATCH] freetype/truetype: implement MSIRP instruction. R=golang-dev, nigeltao, bsiegert CC=golang-dev https://codereview.appspot.com/16630044 Committer: Nigel Tao --- freetype/truetype/hint.go | 23 +++++++++++++++++++++++ freetype/truetype/opcodes.go | 6 +++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/freetype/truetype/hint.go b/freetype/truetype/hint.go index 86647c3..e7b6d11 100644 --- a/freetype/truetype/hint.go +++ b/freetype/truetype/hint.go @@ -550,6 +550,29 @@ func (h *Hinter) run(program []byte, pCurrent, pUnhinted, pInFontUnits []Point, } h.gs.loop = 1 + case opMSIRP0, opMSIRP1: + top -= 2 + i := h.stack[top] + distance := f26dot6(h.stack[top+1]) + + // TODO: special case h.gs.zp[1] == 0 in C Freetype. + ref := h.point(0, current, h.gs.rp[0]) + p := h.point(1, current, i) + if ref == nil || p == nil { + return errors.New("truetype: hinting: point out of range") + } + curDist := dotProduct(f26dot6(p.X-ref.X), f26dot6(p.Y-ref.Y), h.gs.dv) + + // Set-RP0 bit. + if opcode == opMSIRP1 { + h.gs.rp[0] = i + } + h.gs.rp[1] = h.gs.rp[0] + h.gs.rp[2] = i + + // Move the point. + h.move(p, distance-curDist, true) + case opALIGNRP: if top < int(h.gs.loop) { return errors.New("truetype: hinting: stack underflow") diff --git a/freetype/truetype/opcodes.go b/freetype/truetype/opcodes.go index 94b5220..0d467e7 100644 --- a/freetype/truetype/opcodes.go +++ b/freetype/truetype/opcodes.go @@ -68,8 +68,8 @@ const ( opSHZ1 = 0x37 // . opSHPIX = 0x38 // SHift point by a PIXel amount opIP = 0x39 // Interpolate Point - opMSIRP0 = 0x3a - opMSIRP1 = 0x3b + opMSIRP0 = 0x3a // Move Stack Indirect Relative Point + opMSIRP1 = 0x3b // . opALIGNRP = 0x3c // ALIGN to Reference Point opRTDG = 0x3d // Round To Double Grid opMIAP0 = 0x3e // Move Indirect Absolute Point @@ -274,7 +274,7 @@ var popCount = [256]uint8{ 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, q, // 0x00 - 0x0f 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, // 0x10 - 0x1f 1, 1, 0, 2, 0, 1, 1, q, q, q, 2, 1, 1, 0, 1, 1, // 0x20 - 0x2f - 0, 0, q, q, q, q, 1, 1, 1, 0, q, q, 0, 0, 2, 2, // 0x30 - 0x3f + 0, 0, q, q, q, q, 1, 1, 1, 0, 2, 2, 0, 0, 2, 2, // 0x30 - 0x3f 0, 0, 2, 1, 2, 1, 1, 1, q, 2, 2, 0, 0, 0, 0, 0, // 0x40 - 0x4f 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 2, 2, 1, q, 1, 1, // 0x50 - 0x5f 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6f