Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add font faces to svg #2797

Merged
merged 6 commits into from
Feb 18, 2016
Merged

Add font faces to svg #2797

merged 6 commits into from
Feb 18, 2016

Conversation

asturur
Copy link
Member

@asturur asturur commented Feb 18, 2016

I will post a test with screenshot and also add tests.

Meanwhile if you want to check the code.

closes #2644

@asturur
Copy link
Member Author

asturur commented Feb 18, 2016

developer need to save the url to font-paths:

fabric.fontPaths['engagement'] = 'http://fonts.gstatic.com/s/engagement/v5/IYnYh0uOiuydvYrbHKIjwfk_vArhqVIZ0nv9q090hN8.woff2';
fabric.fontPaths['plaster'] = 'http://fonts.gstatic.com/s/plaster/v7/Zh-WKr-VgJ8vp42dO2R9mw.woff2';

font url can be a base64 dataurl to embed the file in the xml if needed.

canvas:
image

svg:
image

svg-xml:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="700" height="600" viewBox="0 0 700 600" xml:space="preserve">
<desc>Created with Fabric.js 1.6.0-rc.1</desc>
<defs>
    <style type="text/css"><![CDATA[
        @font-face {
            font-family: 'engagement';
            src: url('http://fonts.gstatic.com/s/engagement/v5/IYnYh0uOiuydvYrbHKIjwfk_vArhqVIZ0nv9q090hN8.woff2');
        }
        @font-face {
            font-family: 'plaster';
            src: url('http://fonts.gstatic.com/s/plaster/v7/Zh-WKr-VgJ8vp42dO2R9mw.woff2');
        }
]]></style>
</defs>
    <g transform="translate(194.17 268.47)">
<rect fill="yellow" x="25.78" y="-117.97" width="7.23" height="67.8"></rect><rect fill="yellow" x="33" y="-117.97" width="11.91" height="67.8"></rect><rect fill="yellow" x="44.92" y="-117.97" width="8.36" height="67.8"></rect><rect fill="yellow" x="53.28" y="-117.97" width="22.25" height="67.8"></rect>     <text font-family="engagement" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: #333; fill-rule: nonzero; opacity: 1;" >
<tspan x="-93.67" y="-65.17" font-family="Helvetica" font-size="20" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">l</tspan><tspan x="-89.22" y="-65.17" font-family="Helvetica" font-size="30" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">o</tspan><tspan x="-72.54" y="-65.17" font-family="Helvetica" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">r</tspan><tspan x="-59.22" y="-65.17" font-family="Helvetica" font-size="50" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">e</tspan><tspan x="-31.41" y="-65.17" font-family="Helvetica" font-size="60" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">m</tspan><tspan x="18.57" y="-65.17" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;"> </tspan><tspan x="25.78" y="-65.17" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">i</tspan><tspan x="33" y="-65.17" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">p</tspan><tspan x="44.92" y="-65.17" font-family="engagement" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">s</tspan><tspan x="53.28" y="-65.17" font-family="Helvetica" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">u</tspan><tspan x="75.52" y="-65.17" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">m</tspan><tspan x="-93.67" y="-4.12" font-family="engagement" font-size="40" font-weight="normal" text-decoration="underline" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">d</tspan><tspan x="-81.62" y="-4.12" font-family="Helvetica" font-size="40" font-weight="normal" text-decoration="underline" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">o</tspan><tspan x="-59.37" y="-4.12" font-style="italic" text-decoration="underline" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: green; fill-rule: ; opacity: 1;">l</tspan><tspan x="-52.53" y="-4.12" font-family="engagement" font-size="40" font-style="italic" font-weight="normal" text-decoration="underline" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: green; fill-rule: ; opacity: 1;">o</tspan><tspan x="-41.46" y="-4.12" font-family="Helvetica" font-size="40" font-style="italic" font-weight="normal" text-decoration="underline" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: green; fill-rule: ; opacity: 1;">r</tspan><tspan x="-93.67" y="48.31" font-weight="bold" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: blue; fill-rule: ; opacity: 1;">s</tspan><tspan x="-85.31" y="48.31" font-family="engagement" font-size="40" font-weight="bold" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: blue; fill-rule: ; opacity: 1;">i</tspan><tspan x="-78.08" y="48.31" font-family="Helvetica" font-size="40" font-weight="bold" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: blue; fill-rule: ; opacity: 1;">t</tspan><tspan x="-64.76" y="48.31" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;"> </tspan><tspan x="-57.55" y="48.31" font-family="Courier" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">A</tspan><tspan x="-33.55" y="48.31" font-family="Courier" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">m</tspan><tspan x="-9.55" y="48.31" font-family="Courier" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">e</tspan><tspan x="14.46" y="48.31" font-family="Courier" font-size="40" font-weight="normal" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">t</tspan><tspan x="-93.67" y="100.74" font-family="Impact" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #666; fill-rule: ; opacity: 1;">c</tspan><tspan x="-73.88" y="100.74" font-family="Impact" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #666; fill-rule: ; opacity: 1;">o</tspan><tspan x="-53.43" y="100.74" font-family="Impact" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #666; fill-rule: ; opacity: 1;">n</tspan><tspan x="-32.51" y="100.74" font-family="Impact" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #666; fill-rule: ; opacity: 1;">s</tspan><tspan x="-13.69" y="100.74" font-family="Impact" font-size="40" font-weight="normal" text-decoration="line-through" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #666; fill-rule: ; opacity: 1;">e</tspan><tspan x="6.76" y="100.74" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">c</tspan><tspan x="15.96" y="100.74" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">t</tspan><tspan x="23.13" y="100.74" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">e</tspan><tspan x="32.33" y="100.74" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">t</tspan><tspan x="39.5" y="100.74" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">u</tspan><tspan x="52.06" y="100.74" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">r</tspan>     </text>
    </g>
    <g transform="translate(496.57 229.15)">
        <text font-family="plaster" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: #333; fill-rule: nonzero; opacity: 1;" >
<tspan x="-96.07" y="-43.45" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">f</tspan><tspan x="-66.09" y="-43.45" font-family="plaster" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">o</tspan><tspan x="-36.13" y="-43.45" font-family="Helvetica" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: red; fill-rule: ; opacity: 1;">o</tspan><tspan x="-13.89" y="-43.45" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;"> </tspan><tspan x="6.13" y="-43.45" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">b</tspan><tspan x="36.09" y="-43.45" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">a</tspan><tspan x="66.05" y="-43.45" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: #333; fill-rule: ; opacity: 1;">r</tspan>           <tspan x="-96.07" y="8.98" fill="#333">baz</tspan>
<tspan x="-96.07" y="61.42" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: blue; fill-rule: ; opacity: 1;">q</tspan><tspan x="-66.11" y="61.42" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: blue; fill-rule: ; opacity: 1;">u</tspan><tspan x="-36.15" y="61.42" font-family="plaster" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: blue; fill-rule: ; opacity: 1;">u</tspan><tspan x="-6.19" y="61.42" font-family="Helvetica" font-size="40" font-weight="normal" style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: blue; fill-rule: ; opacity: 1;">x</tspan>       </text>
    </g>
    <g transform="translate(440.43 435.55) rotate(-10) scale(0.5 0.5)">
        <text font-family="engagement" font-size="40" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: #0aded9; fill-rule: nonzero; opacity: 1;" >
            <tspan x="-164.57" y="-69.66" fill="#0aded9">Lorem ipsum dolor sit amet,</tspan>
            <tspan x="-164.57" y="-17.23" fill="#0aded9">consectetur adipisicing elit,</tspan>
            <tspan x="-164.57" y="35.2" fill="#0aded9">sed do eiusmod tempor incididunt</tspan>
            <tspan x="-164.57" y="87.63" fill="#0aded9">ut labore et dolore magna aliqua.</tspan>
        </text>
    </g>
</svg>

@kangax do you think is ok?
i will try to add some test, but just if you are ok with this feature.

@asturur
Copy link
Member Author

asturur commented Feb 18, 2016

Adding test anyway e prettier svg formatting for iText char tspans.

kangax added a commit that referenced this pull request Feb 18, 2016
@kangax kangax merged commit 3adaec2 into fabricjs:master Feb 18, 2016
@asturur
Copy link
Member Author

asturur commented Feb 18, 2016

Test was not complete, i all add it now.

@howdu
Copy link

howdu commented May 29, 2017

@asturur could you please add a way of importing css so that it can work with bold/italic more easily.

<style type="text/css"><![CDATA[
     @import url(http://fonts.googleapis.com/css?family=Indie+Flower);
]]></style>

@asturur
Copy link
Member Author

asturur commented May 30, 2017

can you explain better?

1 similar comment
@asturur
Copy link
Member Author

asturur commented May 30, 2017

can you explain better?

@howdu
Copy link

howdu commented May 30, 2017

I use the same custom font but with bold/italic. Currently I have to add all fonts with different font names.

<style type="text/css"><![CDATA[
		@font-face {
			font-family: 'Roboto';
			src: url('https://fonts.gstatic.com/s/roboto/v16/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2');
		}
		@font-face {
			font-family: 'Roboto Bold';
			src: url('https://fonts.gstatic.com/s/roboto/v16/d-6IYplOFocCacKzxwXSOFtXRa8TVwTICgirnJhmVJw.woff2');
		}
]]></style>

If it worked with import lot cleaner but it only works without CDATA

<style type="text/css">
     @import url(https://fonts.googleapis.com/css?family=Roboto:400,700,700i);
</style>

Here's example showing it working: https://github.com/marians/test-webfonts-in-svg

@asturur
Copy link
Member Author

asturur commented May 30, 2017

is not something i have to change.
Are you properly waiting for the fonts to load before rendendering an svg with fabric?
do you have a failing fiddle with an import statement and a canvas that cannot display the correct font?

@halilozanyilmaz
Copy link

@asturur I have same issue with howdu, how can I add multiple woff2 files to the fontpath for the same font? Example below link:

https://fonts.googleapis.com/css?family=Pangolin

There are 5 different woff2 files.

@wesleyguirra
Copy link

It seems that fabric already add font path to fabric.fontPaths, but the generated svg doesn't seems to export correctly with fonts.

@ardivales
Copy link

Hello
when I click a Google font it does not apply to SVG. This method does not work for all fonts?
an idea?

@asturur
Copy link
Member Author

asturur commented Aug 29, 2019

click where?

@vppise
Copy link

vppise commented Feb 1, 2020

i have created svg from canvas.toSVG(); but that svg file not includes includes style tag
i have attached file below. it not converting font while converting it svg to pdf please suggest
font conversion.txt

@asturur
Copy link
Member Author

asturur commented Feb 2, 2020

svg to pdf conversion is nothing we can help with here.
Embedding fonts in a pdf is a specific process with its own set of skills

@vppise
Copy link

vppise commented Feb 3, 2020

@asturur if you have saw my attached txt file, in the svg tag inside the tag <style> tag is missing while i am creating svg by canvas.toSVG(). if i add manually the style tag with google font link it is working. so will you suggest me is there any other option to create svg from canvas.?

@asturur
Copy link
Member Author

asturur commented Feb 3, 2020

fabricjs does publish the fonts if correct linked as shown in the second comment of this issue. If it does not do it, please reproduce it.

@vppise
Copy link

vppise commented Feb 4, 2020

@asturur Thank you for your response. i have added font supported library to my pdf convertor library and problem solved.

@KKzLEO
Copy link

KKzLEO commented Nov 22, 2022

hi, I have the same question with howdu, is there any way we can directly attach style tag in the svg? because the google api https://fonts.googleapis.com/css?family=Crimson%20Text will return @font-face style instead of font file so we can't put that api link in the fabric.fontPaths

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fonts style missing from SVG
8 participants