What transforms does FreeType do to a glyph? - truetype

I find that freetype2 doesn't handle subglyphs' placements correctly (or I'm perhaps using it wrong). For example, when I try to render the 'Ã', the A with the tilde on top of it, I get this:
http://i.imgur.com/3pkYfO3.png Ignore the little tails and red text everywhere; the point is that the tilde is intersecting with the A.
When I specify the FT_LOAD_NO_RECURSE flag, and then add the two subglyphs on my own (using the offsets from arg1 and arg2 from FT_Get_SubGlyph_Info), it's correct: http://i.imgur.com/TrjgHVs.png
It's a similar story with almost every other compound character.
Perhaps relevant: the exact calls I'm using are:
FT_Library library = { };
FT_Init_FreeType(&library);
...
FT_Face face = { };
FT_New_Face(library, "arial.ttf", 0, &face);
...
FT_Set_Char_Size(face, 10, 10, 72, 72);
...
FT_Load_Glyph(face, glyphIndex, FT_LOAD_NO_BITMAP);
So, first question: am I somehow using freetype2 wrong?
If it is indeed a bug in freetype2, and I have to proceed with FT_LOAD_NO_RECURSE, the problem I have is that FT_LOAD_NO_RECURSE implies FT_LOAD_NO_SCALE and FT_LOAD_IGNORE_TRANSFORM. The effect is that my resulting characters have very weird coordinates. For example, the slash character, '/', used to have these four points:
top: 28,46
right: 34,43
left: 4,1
bottom: 10,-2
but now that there's no scaling or transforming, I get these points:
top: 901,1474
right: 1087,1376
bottom: 328,-74
left: 142,24
The main question: How do I get back to the first set of coordinates? What do I add/multiply?
Many thanks!

Turns out this was the answer:
FT_Load_Glyph(face, glyphIndex, FT_LOAD_NO_BITMAP);
float scaleX = face->size->metrics.x_scale / 65536.0;
float scaleY = face->size->metrics.y_scale / 65536.0;
for each point:
point = vec2(round(point.point.x * scaleX), round(point.point.y * scaleY));
face->size->metrics has how much we're supposed to scale it to get from grid units to font units. Then, we gotta round at the end. This must be what happens when FT_LOAD_NO_SCALE isn't set.

Related

createjs combine 2 shapes in a mask

I have a symbol S1 with two shapes (lets say sh0 and sh1). On the stage I have an instance of another symbol mc. At run time, I will create an instance mc1 of the symbol S1. Using createjs, how can I use mc1 as a mask for mc?
I assume when you say "symbol", you mean a graphic or MovieClip in Adobe Animate. Unfortunately, you can only use a CreateJS "Shape" as a mask directly. There are a few options:
Combine the shapes into one yourself.
Combine the instructions. This is a bit dirty, but you could in theory concat the graphic instructions from one shape into another. I suspect this would have issues if the Shape instances have different x/y positions.
symbol.shape1.graphics._instructions.concat(symbol.shape2.graphics._instructions);
Cache the symbol as use it as a Mask with AlphaMaskFilter. The example in the documents should get you what you want.
var box = yourSymbol;
box.cache(0, 0, 100, 100);
var bmp = new createjs.Bitmap("path/to/image.jpg");
bmp.filters = [
new createjs.AlphaMaskFilter(box.cacheCanvas)
];
bmp.cache(0, 0, 100, 100);
The 3rd is probably your best option, but it is limiting and can be performance intensive due to the use of the filter (especially if content changes and you have to update it constantly).
Feel free to post more details on what you are working with in order to get a better recommendation.
Cheers.

libgdx camera position using viewport

I am rather experiences libgdx developer but I struggle with one issue for some time so I decided to ask here.
I use FillViewport, TiledMap, Scene2d and OrtographicCamera. I want the camera to follow my player instance but there are bounds defined (equal to mapsize). It means that camera will never ever leave outside of map, so when player comes to an end of the map camera stops following and he goes to the edge of the screen itself. Maybe sounds complicated but it's simple and I am sure that you know what I mean, it's used in every game.
I calculated 4 values:
minCameraX = camera.viewportWidth / 2;
minCameraY = camera.viewportHeight / 2;
maxCameraX = mapSize.x camera.viewportWidth / 2;
maxCameraY = mapSize.y - camera.viewportHeight / 2;
I removed not necessary stuff like unit conversion, camera.zoom etc. Then I set the camera position like this:
camera.position.set(Math.min(maxCameraX, Math.max(posX, minCameraX)), Math.min(maxCameraY, Math.max(posY, minCameraY)), 0);
(posX, posY is player position) which is basically setting camera to player position but if it's to high or too low it sets it to max or min defined before in right axis. (I also tries MathUtils.clamp() and it works the same.
Everything is perfect until now. Problem occures when aspect ratio changes. By default I use 1280x768 but my phone has 1280x720. Because of that bottom and top edges of the screen are cut off because of the way how FillViewport works. Because of that part of my map is cut off.
I tried to modify maximums and minimums, calculate differences in ratio and adding them to calculations, changing camera size, different viewports and some other stuff but without success.
Can you guys help?
Thanks
I tried solution of noone and Tenfour04 from comments above. Both are not perfect but I am satisified enough i guess:
noone:
camera.position.x = MathUtils.clamp(camera.position.x, screenWidth/2 + leftGutter, UnitConverter.toBox2dUnits(mapSize.x) - screenWidth/2 + rightGutter);
camera.position.y = MathUtils.clamp(camera.position.y, screenHeight/2 + bottomGutter, UnitConverter.toBox2dUnits(mapSize.y) - screenHeight/2 - topGutter);
It worked however only for small spectrum of resolutions. For strange resolutions where aspect ratio is much different than default one I've seen white stripes after border. It means that whole border was printer and some part of the world outside of border. I don't know why
Tenfour04:
I changed viewport to ExtendViewport. Nothing is cut off but in different aspect ratios I also can see world outside of borders.
Solution for both is to clear screen with same color as the border is and background of level separatly which gave satisfying effect in both cases.
It stil has some limitations. As border is part of the world (tiled blocks) it's ok when it has same color. In case border has different colors, rendering one color outside of borders won't be a solution.
Thanks noone and Tenfour04 and I am still opened for suggestions:)
Here are some screenshots:
https://www.dropbox.com/sh/00h947wkzo73zxa/AAADHehAF4WI8aJ8bu4YzB9Va?dl=0
Why don't you use FitViewport instead of FullViewport? That way it won't cut off your screen, right?
It is a little bit late, but I have a solution for you without compromises!
Here width and height are world size in pixels. I use this code with FillViewport and everything works excellent!
float playerX = player.getBody().getPosition().x*PPM;
float playerY = player.getBody().getPosition().y*PPM;
float visibleW = viewport.getWorldWidth()/2 + (float)viewport.getScreenX()/(float)viewport.getScreenWidth()*viewport.getWorldWidth();//half of world visible
float visibleH = viewport.getWorldHeight()/2 + (float)viewport.getScreenY()/(float)viewport.getScreenHeight()*viewport.getWorldHeight();
float cameraPosx=0;
float cameraPosy=0;
if(playerX<visibleW){
cameraPosx = visibleW;
}
else if(playerX>width-visibleW){
cameraPosx = width-visibleW;
}
else{
cameraPosx = playerX;
}
if(playerY<visibleH){
cameraPosy = visibleH;
}
else if(playerY>height-visibleH){
cameraPosy = height-visibleH;
}
else{
cameraPosy = playerY;
}
camera.position.set(cameraPosx,cameraPosy,0);
camera.update();

Less CSS - How to return value in viewport with (vw)

The Less percentage function returns value in (%) - wow!
element {
width: percentage(700 / 1400);
}
will compile to:
element {
width: 50%;
}
What would be the best way or syntax to get the value in (vw) so the style will compile to:
(bare in mind that the division function needs to be used. (700 / 1400))
element {
width: 50vw;
}
The best way to achieve the expected output would be to multiply the value by 100vw. This would be the most meaningful and easily understandable method.
a{
width: 700/1400 * 100vw;
}
The below method of using unit() function works too but I wouldn't really recommend it.
One of the primary reasons why I wouldn't recommend it is because I am not sure if that is supposed to work as it does. The unit() function is supposed to take a number as its first parameter and add the units to it but a percentage value is not exactly a number and this may not work in future versions depending on how the Less core team view it.
I read the docs and it seems like the first parameter can be a number with or without a dimension but I still wouldn't recommend it because the earlier method is far more easier to understand than the usage of functions.
b{
width: unit(percentage(700/1400), vw);
}

How can I instruct less to ignore math for certain styles?

I'm using the new calc function in CSS to get the width for an object, as in:
width: calc(100% - 40px);
Unfortunately, since this is in a LESS file, LESS is "helpfully" pre-converting this to 60% during compile time.
I want less to ignore math when it's in a calc function since I need the browser to do this calculation, not less.
Is there anyway I can make LESS ignore this calculation so I can pass it straight to the browser?
Use it through an escaped string:
width: ~"calc(100% - 40px)";
Which outputs purely as CSS:
width: calc(100% - 40px);
Instead of precalculating width: calc(60%) (as you are experiencing).
NOTE: LESS 1.4+ does not need this escaped string if the strict-math mode is set, as all "math" then requires its own parenthesis to trigger. So LESS 1.4+ in that mode could be used as you originally had it, and if you wanted it to do the math, it would need extra parentheses and a unit() function like so: width: calc((100% - unit(40px)));.

How to correctly paint a huge image

I'm fairly new to wxWidgets so please bear with me. Let's say I have a 10Kx10K image and my wxScrolledWindow has a size of 640x480. I load the whole image into a wxBitmap which I use in my paint function.
Now in my OnPaint function I just say
wxPaintDC dc(this);
dc.DrawBitmap(_Bitmap, 0, 0 );
This somewhat works for the first few paints but soon the Window content is out order and artifacts appear. This happens very fast when I move a scroll bar back and forth very quickly.
I use the latest wxWidgets on a Windows 7 machine.
So, how can I improve my painting code?
Many thanks,
Christian
Using a 10000x10000 wxBitmap is a bad idea on its own, it may simply fail to be created on an older system (that's 400MiB of video RAM!). Drawing it entirely is sheer madness.
I don't know where does your data come from but in a typical case of e.g. a map to be shown on screen, you should break it into tiles, convert the tiles that are currently visible on screen to wxBitmap (or several of them) and draw only those.
Then you may optimize your drawing by using double buffering (which is relatively useless under Windows 7 that double buffers everything on its own) and otherwise, but you should be using a reasonably-sized backing store bitmap.
This sounds like something that might be helped by using double buffering.
The first thing to start trying is to replace wxPaintDC with wxBufferedPaintDC
For more suggestions, here is a wiki article on the subject: http://wiki.wxwidgets.org/Flicker-Free_Drawing
As Ravenspoint kindly pointed out, there is an article on wxWidgets' wiki. So according to that article two things need to happen. First override the EVT_ERASE_BACKGROUND with an empty function.
void Canvas::EraseBackground( wxEraseEvent& WXUNUSED(event))
{
}
And second to implement a basic double buffering scheme. Here is how I did it.
void Canvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
int x, y;
GetViewStart(&x, &y);
wxRect Client_Area = GetClientRect();
int width = Client_Area.width;
int height = Client_Area.height;
wxBitmap Current = _Bitmap.GetSubBitmap(wxRect( x * 10, y * 10, width, height ));
wxPaintDC dc(this);
dc.DrawBitmap(Current, 0, 0, false );
}
My scroll rate for both x and y is set to 10. That's why I multiply the view start coordinates.
Any more insight is very welcome.
Thanks,
Christian