# HG changeset patch # User Michael Pavone # Date 1427259028 25200 # Node ID 50760ba52b1143bfce7c0f4350f72fff50fe66c9 # Parent 4a79311dbd2932ac4a6c52da3949730d51f90039 Added basic rendering of strings to freetype demo diff -r 4a79311dbd29 -r 50760ba52b11 modules/freetype.tp --- a/modules/freetype.tp Tue Mar 24 21:49:45 2015 -0700 +++ b/modules/freetype.tp Tue Mar 24 21:50:28 2015 -0700 @@ -224,6 +224,14 @@ ccall: makeSlot 1 opaque } + llMessage: unitsPerEm withVars: { + u16ret <- obj_uint16 ptr + } andCode: { + u16ret <- make_object: (addr_of: obj_uint16_meta) NULL 0 + u16ret num!: (face units_per_EM) + u16ret + } + firstChar <- { _helper getFirstChar: faceOpaque _makeChar } diff -r 4a79311dbd29 -r 50760ba52b11 samples/freetype.tp --- a/samples/freetype.tp Tue Mar 24 21:49:45 2015 -0700 +++ b/samples/freetype.tp Tue Mar 24 21:50:28 2015 -0700 @@ -21,8 +21,8 @@ linearDesign ] from: (freetype loadFlags) - makeAtlas <- :renderer face size dpi color { - face setCharSize: size res: dpi + makeAtlas <- :renderer face fontSize dpi color { + face setCharSize: fontSize res: dpi slot <- face glyphSlot glyphs <- #[] @@ -61,6 +61,12 @@ atlasX <- -1 atlasY <- -1 + atlasRect <- { + sdl rect: atlasX atlasY size: width height + } + destRect <- :x y { + sdl rect: x + leftOffset y - topOffset size: width height + } <= <- :other { if: height > (other height) { @@ -207,6 +213,32 @@ } skinny value: :curGlyph { + curGlyph atlasX!: curX + curGlyph atlasY!: curY + y <- 0 + dstY <- curY + idx <- curGlyph pixelOffset + while: { y < (curGlyph height) } do: { + dstIdx <- dstY * pitch + curX * 4 + x <- 0 + while: { x < (curGlyph width) } do: { + //FIXME: This will probably only work on little endian machines + bytearr set: dstIdx (pixels get: idx) + dstIdx <- dstIdx + 1 + bytearr set: dstIdx (color r) + dstIdx <- dstIdx + 1 + bytearr set: dstIdx (color g) + dstIdx <- dstIdx + 1 + bytearr set: dstIdx (color b) + dstIdx <- dstIdx + 1 + + idx <- idx + 1 + x <- x + 1 + } + y <- y + 1 + dstY <- dstY + 1 + } + curX <- curX + (curGlyph width) if: (curGlyph height) > minHeight { minHeight <- curGlyph height @@ -226,11 +258,31 @@ foreach: glyphs :idx glyph { glyphDict set: (glyph charCode) glyph } + _pixelFactor <- ((face unitsPerEm) f64) * 72.0 / (fontSize * (dpi f64)) option value: #{ texture <- drawTex width <- aWidth height <- aHeight glyphs <- glyphDict + drawString:at <- :str :x y { + //pixels to font units + designPosition <- (x f64) * _pixelFactor + charIdx <- 0 + + while: { charIdx < (str byte_length) } do: { + //TODO: UTF-8 + char <- (str byte: charIdx) uint32 + glyph <- glyphs get: char else: { + glyphs get: 0u32 else: { false } + } + texture copyRect: (glyph atlasRect) To: (glyph destRect: x y) + + designPosition <- designPosition + ((glyph hAdvance) f64) + x <- (designPosition / _pixelFactor + 0.5) truncInt32 + + charIdx <- charIdx + 1 + } + } } } none: { print: "Failed to create texture for atlas" @@ -256,9 +308,9 @@ arg <- 1 expectVal <- false optName <- "" - path <- "" windowWidth <- 512 windowHeight <- 512 + posArgs <- #[] while: { arg < (args length) } do: { curArg <- args get: arg if: expectVal { @@ -281,11 +333,13 @@ expectVal <- true optName <- curArg } else: { - path <- curArg + posArgs append: curArg } } arg <- arg + 1 } + path <- posArgs get: 0 + str <- if: (posArgs length) > 1 { posArgs get: 1 } else: { "" } ft <- freetype init maybeFace <- ft faceFromPath: path index: 0 charCodes <- #[] @@ -305,14 +359,18 @@ continue? <- true while: { continue? } do: { renderer clear - y <- 0 - x <- 0 - while: { y < (atlas height) } do: { - copyWidth <- if: (atlas width) < windowWidth { atlas width } else: { windowWidth } - copyHeight <- if: (atlas height) < windowHeight { atlas height } else: { windowHeight } - (atlas texture) copyRect: (sdl rect: 0 y size: copyWidth copyHeight) To: (sdl rect: x 0 size: copyWidth copyHeight) - y <- y + windowHeight - x <- x + copyWidth + if: (str length) > 0 { + atlas drawString: str at: 0 windowHeight / 2 + } else: { + y <- 0 + x <- 0 + while: { y < (atlas height) } do: { + copyWidth <- if: (atlas width) < windowWidth { atlas width } else: { windowWidth } + copyHeight <- if: (atlas height) < windowHeight { atlas height } else: { windowHeight } + (atlas texture) copyRect: (sdl rect: 0 y size: copyWidth copyHeight) To: (sdl rect: x 0 size: copyWidth copyHeight) + y <- y + windowHeight + x <- x + copyWidth + } } renderer present event <- option none