|
10-12-2017, 10:07 AM
|
#1
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
Adding custom fonts to Cairo
I'm wanting to change the font used within Cairo, and have been examining the various font face functions but am getting a bit lost and not sure where to begin. Also, is it possible to import a TrueType font or is it all FreeType?
|
|
|
10-12-2017, 10:30 AM
|
#2
|
Human being with feelings
Join Date: Dec 2015
Posts: 331
|
Quote:
Originally Posted by Bobflip
I'm wanting to change the font used within Cairo, and have been examining the various font face functions but am getting a bit lost and not sure where to begin. Also, is it possible to import a TrueType font or is it all FreeType?
|
Don't know anything about it, but since FreeType supports TrueType, that should be the answer to the second question.
|
|
|
10-12-2017, 11:03 AM
|
#3
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
Ah, well that's a start, cheers!
|
|
|
10-13-2017, 02:52 AM
|
#4
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Look at ycairo_text class if you are using my framework... The best way for using is to create global font in plugin constructor.
|
|
|
10-13-2017, 02:26 PM
|
#5
|
Human being with feelings
Join Date: Jan 2017
Posts: 43
|
This is how I set a global font using Youlean's branch.
In the plugin constructor:
Code:
// Youlean's Cairo base
ycairo_base * base = GetYCAIRO();
// Create base font - this is used in all ycairo_text instances throughout
base -> create_global_font_from_path("/Library/Fonts/Futura.ttc");
Then in a control you'd want some thinglike this:
Code:
// In the control constructor
ycairo_text * yText = new ycairo_text(ycairo_base);
// In the Draw() method
yText -> ycairo_show_text(cr, textChar, textSize, IRECT);
Hope that helps!
MSK
Last edited by MSK; 10-13-2017 at 02:33 PM.
|
|
|
10-14-2017, 05:26 AM
|
#6
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Quote:
Originally Posted by MSK
This is how I set a global font using Youlean's branch.
In the plugin constructor:
Code:
// Youlean's Cairo base
ycairo_base * base = GetYCAIRO();
// Create base font - this is used in all ycairo_text instances throughout
base -> create_global_font_from_path("/Library/Fonts/Futura.ttc");
Then in a control you'd want some thinglike this:
Code:
// In the control constructor
ycairo_text * yText = new ycairo_text(ycairo_base);
// In the Draw() method
yText -> ycairo_show_text(cr, textChar, textSize, IRECT);
Hope that helps!
MSK
|
This is how I am using it:
Code:
class SomeControl: public IControl, ycairo_gui, ycairo_text
{
public:
SomeControl(IPlugBase* pPlug, ycairo_base *ycairo_base, IRECT pR)
: IControl(pPlug, pR), ycairo_gui(ycairo_base, this), ycairo_text(ycairo_base) {}
}
BTW you should never create object with new if you don't really need to. If you want to create object just use ycairo_text textObject;
|
|
|
10-14-2017, 05:31 AM
|
#7
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Creating global font from path is also not ideal. It would be best to ship font with your binary. To do that use:
resource.h
Code:
// Font declaration ---------------------------------------------------------------------
#define FONT_FILE 256 //Must be greater than 255, it should be declared once
#define FONT_ID 102 //Unique ID
#define FONT_PATH "resources/SomeFont.ttf"
//-------------------------------------------------------------------------------------
*.rc
Code:
#include "resource.h"
FONT_ID FONT_FILE FONT_PATH
constructor
Code:
GetYCAIRO()->create_global_font_from_memory(FONT_ID, FONT_FILE, FONT_PATH);
|
|
|
10-14-2017, 07:08 AM
|
#8
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
Thanks everyone for the advice, I'll experiment this weekend, and I certainly plan to ship the font within the binaries.
Up to now I've been using cairo_text_path to draw text, is this compatible with the techniques described, or will I have to do a hefty session of rewriting?
|
|
|
10-14-2017, 07:35 AM
|
#9
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Quote:
Originally Posted by Bobflip
Thanks everyone for the advice, I'll experiment this weekend, and I certainly plan to ship the font within the binaries.
Up to now I've been using cairo_text_path to draw text, is this compatible with the techniques described, or will I have to do a hefty session of rewriting?
|
Filling text path is very expensive on CPU (up to 1000% CPU increase), so you should switch to my methods (ycairo_show_text).
|
|
|
10-14-2017, 07:45 AM
|
#10
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
Blimey, hahaha! Ok, definitely sorting that this weekend.
Although that said, I've been using the paths to create an outline around the text like this:
Code:
// Outline text
cairo_move_to(cr, mDrawRECT.L + x, mDrawRECT.T + y);
cairo_text_path(cr, mStr.Get());
cairo_fill_preserve(cr);
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_set_line_width(cr, 2.56);
cairo_stroke(cr);
// Overlaid non-outline text
cairo_move_to(cr, mDrawRECT.L + x, mDrawRECT.T + y);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_text_path(cr, mStr.Get());
cairo_fill_preserve(cr);
cairo_set_line_width(cr, 0.0);
cairo_stroke(cr);
I can't see a way of doing this directly with ycairo_show_text, although maybe it's possible with ycairo_drop_shadow_stroke?
|
|
|
10-14-2017, 07:57 AM
|
#11
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Quote:
Originally Posted by Bobflip
I can't see a way of doing this directly with ycairo_show_text, although maybe it's possible with ycairo_drop_shadow_stroke?
|
No drop shadow will be even more taxing on CPU. IF you want to outline text you need to use paths. you should look inside ycairo_show_text method to see how to create path with freetype.
|
|
|
10-14-2017, 08:10 AM
|
#12
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
That's the thing, I had a look in there but couldn't work out how to get a path from it, it's a bit over my head at this point.
Code:
void ycairo_text::ycairo_show_text(cairo_t * cr, const char * text, double size, IColor color, IRECT rect, ycairo_text_w_aligement w_aligement, ycairo_text_h_aligement h_aligement)
{
cairo_set_source_rgba(cr, color.R / 255.0, color.G / 255.0, color.B / 255.0, color.A / 255.0);
ycairo_initialize_font_face(cr);
cairo_set_font_size(cr, size);
ycairo_set_text(cr, text);
ycairo_set_text_position(cr, rect, w_aligement, h_aligement);
//// Adding subpixel rendering improves rendering speed by 10% on my system
//cairo_font_options_t *options;
//cairo_get_font_options(cr, options);
//cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
//cairo_set_font_options(cr, options);
//// -----------------------------------------------------------------------
cairo_show_text(cr, text);
ycairo_destroy_font_face();
}
void ycairo_text::ycairo_show_text(cairo_t * cr)
{
cairo_show_text(cr, draw_text);
}
|
|
|
10-14-2017, 08:14 AM
|
#13
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
[QUOTE=Bobflip;1898128]That's the thing, I had a look in there but couldn't work out how to get a path from it, it's a bit over my head at this point.
Read https://www.cairographics.org/manual/index.html
Anyways use cairo_text_path instead of cairo_show_text
|
|
|
10-14-2017, 08:26 AM
|
#14
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
I think that may have been where I learnt how to do it initially! The tutorials there were really handy while learning my way around Cairo.
I'm already using cairo_text_path in the code I posted above (post #10), I guess I could speed things up by using ycairo_show_text for the non-outline text and just use the path for the outline.
|
|
|
10-14-2017, 08:43 AM
|
#15
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Quote:
Originally Posted by Bobflip
I think that may have been where I learnt how to do it initially! The tutorials there were really handy while learning my way around Cairo.
I'm already using cairo_text_path in the code I posted above (post #10), I guess I could speed things up by using ycairo_show_text for the non-outline text and just use the path for the outline.
|
Indeed but you will also speed up things if you use freetype to create font instead of cairo fonts.
|
|
|
10-14-2017, 09:57 AM
|
#16
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
Ok, thanks, will get that on the to-do list.
Having trouble creating the font still though, so I've pasted the code into the relevant bits of a fresh IPlugEffect, dropped a font into resources and dragged it into XCode's resources, and updated FONT_PATH to match, but on both Windows and Mac it bombs out with a Bad Access error at if (global_font) in create_global_font_from_memory.
|
|
|
10-14-2017, 10:09 AM
|
#17
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
Actually, wait. I put it into IPlugEffectCairoGraphics (where I was originally doing the font testing!) and it loads ok, but it wasn't working in my plugin yet. Just going to get the font loading working in IPlugEffectCairoGraphics for now and then try and extrapolate it to mine!
|
|
|
10-14-2017, 11:19 AM
|
#18
|
Human being with feelings
Join Date: Nov 2016
Posts: 341
|
Ok yeah, got it sorted in both the example and in my own code! Not been able to get the cairo path text to line up with the ycairo text, but this seems to do the trick nicely. Thanks for the pointers.
Code:
ycairo_prepare_draw();
ycairo_initialize_font_face(cr);
cairo_set_font_size(cr, 12);
cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
// Find coordinates to centre text
cairo_text_extents_t extents;
cairo_text_extents(cr, outputString, &extents);
double x = (mDrawRECT.W() / 2) - (extents.width / 2 + extents.x_bearing);
cairo_text_extents (cr, "0", &extents); // This gets the vertical centre but ignores the tails on a lower case 'p', for example
double y = (mDrawRECT.H() / 2) - (extents.height / 2 + extents.y_bearing);
// Round off the coordinates to prevent blurring.
x = floor(x);
y = floor(y);
// Outline text
cairo_move_to(cr, mDrawRECT.L + x, mDrawRECT.T + y);
cairo_text_path(cr, outputString);
cairo_fill_preserve(cr);
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_set_line_width(cr, 2.56);
cairo_stroke(cr);
// Overlaid non-outline text
cairo_move_to(cr, mDrawRECT.L + x, mDrawRECT.T + y);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_text_path(cr, outputString);
cairo_fill_preserve(cr);
cairo_set_line_width(cr, 0.0);
cairo_stroke(cr);
ycairo_draw();
return true;
Last edited by Bobflip; 11-12-2017 at 08:37 PM.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 05:59 AM.
|