From d5181302ad65d6ecf07f20bd9b7a41a31d25f4a9 Mon Sep 17 00:00:00 2001 From: Andy Meneely Date: Tue, 25 Nov 2014 00:30:28 -0500 Subject: [PATCH] Implementing ink extent return values --- CHANGELOG.md | 3 ++- lib/squib/api/text.rb | 6 ++++-- lib/squib/graphics/text.rb | 4 ++++ samples/text_options.rb | 18 ++++++++++++++---- spec/graphics/graphics_text_spec.rb | 12 +++++++----- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b768c5b..39ec5e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Squib CHANGELOG -# Custom layouts now support loading & merging multiple Yaml files. Updated README, docs, and sample to document it. +# Custom layouts now support loading & merging multiple Yaml files! Updated README, docs, and sample to document it. +# `text` now returns the ink extent rectangle of the rendered text. Updated docs and sample to document it. # Samples now show that you can use text instead of symbols for things like `center` # Improved logging, and documentation on increasing logger verboseness # Better regression testing technique that tracks when a sample has changed. diff --git a/lib/squib/api/text.rb b/lib/squib/api/text.rb index cf9e2fe..f9d4e98 100644 --- a/lib/squib/api/text.rb +++ b/lib/squib/api/text.rb @@ -36,18 +36,20 @@ module Squib # @option opts ellipsize [:none, :start, :middle, :end, true, false] (:end) When width and height are set, determines the behavior of overflowing text. Also: `true` maps to `:end` and `false` maps to `:none`. Default `:end` # @option opts angle [FixNum] (0) Rotation of the text in radians. Note that this rotates around the upper-left corner of the text box, making the placement of x-y coordinates slightly tricky. # @option opts hint [String] (:nil) draw a rectangle around the text with the given color. Overrides global hints (see {Deck#hint}). - # @return [nil] Returns nothing + # @return [Array] Returns an Array of hashes keyed by :width and :height that mark the ink extents of the text rendered. # @api public def text(opts = {}) opts = needs(opts, [:range, :str, :font, :font_size, :x, :y, :width, :height, :color, :wrap, :align, :justify, :spacing, :valign, :markup, :ellipsize, :hint, :layout, :angle]) + extents = Array.new(@cards.size) opts[:range].each do |i| - @cards[i].text(opts[:str][i], opts[:font][i], opts[:font_size][i], opts[:color][i], + extents[i] = @cards[i].text(opts[:str][i], opts[:font][i], opts[:font_size][i], opts[:color][i], opts[:x][i], opts[:y][i], opts[:width][i], opts[:height][i], opts[:markup][i], opts[:justify][i], opts[:wrap][i], opts[:ellipsize][i], opts[:spacing][i], opts[:align][i], opts[:valign][i], opts[:hint][i], opts[:angle][i]) end + return extents end end diff --git a/lib/squib/graphics/text.rb b/lib/squib/graphics/text.rb index a3e7961..a39d6a0 100644 --- a/lib/squib/graphics/text.rb +++ b/lib/squib/graphics/text.rb @@ -89,6 +89,7 @@ module Squib markup, justify, wrap, ellipsize, spacing, align, valign, hint, angle) Squib.logger.debug {"Placing '#{str}'' with font '#{font}' @ #{x}, #{y}, color: #{color}, angle: #{angle} etc."} + extents = nil use_cairo do |cc| cc.set_source_color(color) cc.translate(x,y) @@ -112,7 +113,10 @@ module Squib valign!(cc, layout, x, y, valign) cc.update_pango_layout(layout) ; cc.show_pango_layout(layout) draw_text_hint(cc,x,y,layout,hint,angle) + extents = { width: layout.extents[1].width / Pango::SCALE, + height: layout.extents[1].height / Pango::SCALE } end + return extents end end diff --git a/samples/text_options.rb b/samples/text_options.rb index f724684..4a9a8d5 100644 --- a/samples/text_options.rb +++ b/samples/text_options.rb @@ -1,5 +1,4 @@ -#!/usr/bin/env ruby -# encoding: utf-8 +# encoding: UTF-8 require 'squib' data = {'name' => ['Thief', 'Grifter', 'Mastermind'], @@ -29,11 +28,22 @@ Squib::Deck.new(width: 825, height: 1125, cards: 3) do text str: 'This text has fixed width, fixed height, center-aligned, middle-valigned, and has a red hint', hint: :red, x: 65, y: 400, - width: 300, height: 200, + width: 300, height: 125, align: :center, valign: 'MIDDLE', #case-insenstive strings allowed too. font: 'Arial 18' - text str: 'Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42', + extents = text str: 'Ink extent return value', + x: 65, y: 550, + font: 'Sans Bold', font_size: [16, 20, 24] + margin = 10 + # Extents come back as an array of hashes, which can get split out like this + ws = extents.inject([]) { |arr, ext| arr << ext[:width] + 10; arr } + hs = extents.inject([]) { |arr, ext| arr << ext[:height] + 10; arr } + rect x: 65 - margin/2, y: 550 - margin/2, + width: ws, height: hs, + radius: 10, stroke_color: :black + + text str: "Ellipsization!\nThe ultimate question of life, the universe, and everything to life and everything is 42", hint: :green, font: 'Arial 22', x: 450, y: 400, width: 280, height: 180, diff --git a/spec/graphics/graphics_text_spec.rb b/spec/graphics/graphics_text_spec.rb index f7af337..98c9562 100644 --- a/spec/graphics/graphics_text_spec.rb +++ b/spec/graphics/graphics_text_spec.rb @@ -13,6 +13,7 @@ describe Squib::Card, '#text' do it 'make all the expected calls on a smoke test' do mock_squib_logger(@old_logger) do + extent = Pango::Rectangle.new(50,60,100,200) expect(Squib.logger).to receive(:debug).once expect(@context).to receive(:save).once expect(@context).to receive(:set_source_color).once @@ -31,7 +32,7 @@ describe Squib::Card, '#text' do expect(@layout).to receive(:spacing=).with(1.0 * Pango::SCALE).once expect(@context).to receive(:update_pango_layout).once expect(@layout).to receive(:height).once.and_return(25) - expect(@layout).to receive(:extents).once.and_return([0,0]) + expect(@layout).to receive(:extents).thrice.and_return([nil,extent]) expect(@context).to receive(:update_pango_layout).once expect(@context).to receive(:show_pango_layout).once expect(@context).to receive(:restore).once @@ -41,10 +42,11 @@ describe Squib::Card, '#text' do # x, y, width, height, # markup, justify, wrap, ellipsize, # spacing, align, valign, hint, angle) - card.text('foo', 'Sans 12', nil, '#abc', - 10, 15, 20, 25, - nil, false, false, false, - 1.0, :left, :top, nil, 0.0) + ret = card.text('foo', 'Sans 12', nil, '#abc', + 10, 15, 20, 25, + nil, false, false, false, + 1.0, :left, :top, nil, 0.0) + expect(ret).to eq({width: 0, height: 0}) end end end