text: rewrite embedding to use set_shape_renderer

No more arcane unicode magic!

Closes #177

Related to #170, #171, #158, #103, and #153 too.
This commit is contained in:
Andy Meneely
2016-09-15 15:19:56 -04:00
parent 0501a94bac
commit ee2ed28550
10 changed files with 267 additions and 102 deletions
+67 -5
View File
@@ -30,6 +30,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Take 11 :tool: and gain 2 :health:. Take <b>2</b> :tool: <i>and gain 3 :purse: if level 2.</i>"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
@@ -53,6 +54,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Middle align: Take 1 :tool: and gain 2 :health:. Take 2 :tool: and gain 3 :purse:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -76,6 +78,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["This :tool: aligns on the bottom properly. :purse:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -91,16 +94,17 @@ cairo: translate([600, 0])
cairo: rotate([0])
cairo: move_to([0, 0])
pango: font_description=([MockDouble])
pango: text=(["Wrapping multiples: These are 1 :tool::tool::tool: and these are multiple :tool::tool: :tool::tool:"])
pango: text=(["Yes, this wraps strangely. We are trying to determine the cause. These are 1 :tool::tool::tool: and these are multiple :tool::tool: :tool::tool:"])
pango: width=([184320])
pango: height=([307200])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Wrapping multiples: These are 1 :tool::tool::tool: and these are multiple :tool::tool: :tool::tool:"])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
pango: markup=(["Yes, this wraps strangely. We are trying to determine the cause. These are 1 :tool::tool::tool: and these are multiple :tool::tool: :tool::tool:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
cairo: rounded_rectangle([0, 0, 0, 0, 0, 0])
cairo: set_source_color([:cyan])
@@ -122,6 +126,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([true])
pango: markup=([":tool:Justify will :tool: work too, and :purse: with more words just for fun"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -145,6 +150,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment right>])
pango: justify=([false])
pango: markup=(["Right-aligned works :tool: with :health: and :purse:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -168,6 +174,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment center>])
pango: justify=([false])
pango: markup=([":tool:Center-aligned works :tool: with :health: and :purse:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
@@ -192,6 +199,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment center>])
pango: justify=([false])
pango: markup=(["foo"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
@@ -216,6 +224,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment center>])
pango: justify=([false])
pango: markup=(["foo"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -240,6 +249,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment center>])
pango: justify=([false])
pango: markup=(["foo"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -260,9 +270,10 @@ pango: width=([389120])
pango: height=([153600])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment center>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=([":tool: Death to Nemesis bug 103!! :purse:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -280,6 +291,54 @@ cairo: set_line_width([2.0])
cairo: stroke([])
pango: ellipsized?([])
cairo: restore([])
cairo: save([])
cairo: set_source_color(["black"])
cairo: translate([400, 640])
cairo: rotate([0])
cairo: move_to([0, 0])
pango: font_description=([MockDouble])
pango: text=(["You can adjust the icon with dx and dy. Normal: :tool: Adjusted: :heart:"])
pango: width=([184320])
pango: height=([307200])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["You can adjust the icon with dx and dy. Normal: :tool: Adjusted: :heart:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
cairo: rounded_rectangle([0, 0, 0, 0, 0, 0])
cairo: set_source_color([:magenta])
cairo: set_line_width([2.0])
cairo: stroke([])
pango: ellipsized?([])
cairo: restore([])
cairo: save([])
cairo: set_source_color(["black"])
cairo: translate([600, 640])
cairo: rotate([0])
cairo: move_to([0, 0])
pango: font_description=([MockDouble])
pango: text=(["Native sizes work too\n:tool:\n\n\n\n\n\n:shiny-purse:\n\n\n\n\n\n:tool2:"])
pango: width=([184320])
pango: height=([486400])
pango: wrap=([#<Pango::Layout::WrapMode word-char>])
pango: ellipsize=([#<Pango::Layout::EllipsizeMode end>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Native sizes work too\n:tool:\n\n\n\n\n\n:shiny-purse:\n\n\n\n\n\n:tool2:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
cairo: rounded_rectangle([0, 0, 0, 0, 0, 0])
cairo: set_source_color([:magenta])
cairo: set_line_width([2.0])
cairo: stroke([])
pango: ellipsized?([])
cairo: restore([])
surface: write_to_png(["_output/embed_00.png"])
cairo: antialias=(["subpixel"])
cairo: antialias=(["subpixel"])
@@ -299,6 +358,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Take 1 :tool: and gain 2 :health:."])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -323,6 +383,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Take 1 :tool: and gain 2 :health:."])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
@@ -347,6 +408,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Take 1 :tool: and gain 2 :health:."])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0.0])
cairo: move_to([0, 0.0])
cairo: show_pango_layout([MockDouble])
+3
View File
@@ -803,6 +803,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Embedded icons! Take 1 :tool: and gain 2:health:. If Level 2, take 2 :tool:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
@@ -821,6 +822,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Embedded icons! Take 1 :tool: and gain 2:health:. If Level 2, take 2 :tool:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
@@ -839,6 +841,7 @@ pango: ellipsize=([#<Pango::Layout::EllipsizeMode none>])
pango: alignment=([#<Pango::Layout::Alignment left>])
pango: justify=([false])
pango: markup=(["Embedded icons! Take 1 :tool: and gain 2:health:. If Level 2, take 2 :tool:"])
pango: attributes=([Pango::AttrList])
cairo: move_to([0, 0])
cairo: move_to([0, 0])
cairo: show_pango_layout([MockDouble])
+73
View File
@@ -0,0 +1,73 @@
require 'spec_helper'
require 'squib/graphics/embedding_utils'
describe Squib::EmbeddingUtils do
context(:indices) do
it 'returns nothing when given nothing' do
expect(Squib::EmbeddingUtils.indices('just some text', [])).to eq({})
end
it 'returns emptiness for given keys that are not in the string' do
str = 'just some text'
keys = [':tool:']
expect(Squib::EmbeddingUtils.indices(str, keys)).to eq({
':tool:' => []
})
end
it 'returns correctly for one key, one time' do
str = 'some :tool: text'
keys = [':tool:']
expect(Squib::EmbeddingUtils.indices(str, keys)).to eq({
':tool:' => [5..11]
})
end
it 'handles one key, multiple times' do
str = 'some :tool: text :tool:'
keys = [':tool:']
expect(Squib::EmbeddingUtils.indices(str, keys)).to eq({
':tool:' => [5..11, 17..23]
})
end
it 'handles one key, multiple times next to each other' do
str = 'some :tool::tool: text'
keys = [':tool:']
expect(Squib::EmbeddingUtils.indices(str, keys)).to eq({
':tool:' => [5..11, 11..17]
})
end
it 'handles multiple keys, one time each' do
str = 'some :tool: heart text'
keys = %w(:tool: heart)
expect(Squib::EmbeddingUtils.indices(str, keys)).to eq({
':tool:' => [5..11],
'heart' => [12..17]
})
end
it 'handles multiple keys, multiple times each' do
str = ':tool:some :tool: heart text heart tool'
keys = %w(:tool: heart)
expect(Squib::EmbeddingUtils.indices(str, keys)).to eq({
':tool:' => [0..6, 11..17],
'heart' => [18..23, 29..34]
})
end
it 'handles multibyte properly' do
str = '💡 📷 :tool: heart text'
keys = %w(:tool: heart 💡)
expect(Squib::EmbeddingUtils.indices(str, keys)).to eq({
':tool:' => [10..16],
'heart' => [17..22],
'💡' => [3..4]
})
end
end
end
+5 -1
View File
@@ -65,6 +65,7 @@ def scrub_hex(str)
str.gsub(/0x\w{1,8}/, '')
.gsub(/ptr=\w{1,8}/, '')
.gsub(/#<Pango::FontDescription:.*>/, '')
.gsub(/#<Pango::AttrList:.*>/, 'Pango::AttrList')
.gsub(/#<Cairo::ImageSurface:.*>/, 'ImageSurface')
.gsub(/#<Cairo::LinearPattern:.*>/, 'LinearPattern')
.gsub(/#<Cairo::RadialPattern:.*>/, 'RadialPattern')
@@ -103,6 +104,8 @@ def mock_cairo(strio)
allow(pango).to receive(:alignment).and_return(Pango::Layout::Alignment::LEFT)
allow(pango).to receive(:text).and_return('foo')
allow(pango).to receive(:context).and_return(pango_cxt)
allow(pango).to receive(:attributes).and_return(nil)
allow(pango_cxt).to receive(:set_shape_renderer)
allow(pango_cxt).to receive(:font_options=)
allow(iter).to receive(:next_char!).and_return(false)
allow(iter).to receive(:char_extents).and_return(Pango::Rectangle.new(5, 5, 5, 5))
@@ -120,7 +123,8 @@ def mock_cairo(strio)
end
%w(font_description= text= width= height= wrap= ellipsize= alignment=
justify= spacing= markup= ellipsized?).each do |m|
justify= spacing= markup= ellipsized? attributes=
set_shape_renderer).each do |m|
allow(pango).to receive(m) {|*args| strio << scrub_hex("pango: #{m}(#{args})\n") }
end