Old 08-02-2018, 01:50 AM   #1
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,681
Default Q: gfx_blit: Rotate text -90 degrees ?

Here's another one I am having problems getting right: I wish to display some text rotated by -90 degrees, thus:


Here's my lua code so far:

Code:
gfx.dest=127;               -- draw to offscreen buffer
LW, LH = gfx.measurestr("... Rotated text ...")
gfx.setimgdim(127, LW, LH)
gfx.x =0; gfx.y = 0; set_colour(CYAN); gfx.a = 0.80
gfx.printf("%s", ... Rotated text ...")  -- so far, so good.

gfx.dest=-1;                -- back to on-screen
gfx.x = 200;  gfx.y = 200; 
gfx.blit(127, 1, 270/360 *2*3.14159,    -- source, scale, rotation (in radians) [, 
         0, 0, LW, LH,                          -- srcx, srcy, srcw, srch, 
         400, 400, LH, LW,  -- destx, desty, destw, desth, (yep, switched around)
         0, 0)                                     -- rotxoffs, rotyoffs])
What am I missing?
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 08-02-2018, 05:25 AM   #2
RobU
Human being with feelings
 
RobU's Avatar
 
Join Date: Sep 2009
Posts: 863
Default

Rotating while blitting does not rotate the destination rectangle. This code uses a rect large enough to take the text at all angles.

Code:
gfx.init("rotated_blit...?", 400, 400, 0, 100, 100)
gfx.clear = 0

LW, LH = gfx.measurestr("...Rotated Text...")
gfx.setimgdim(127, LW, LW)

gfx.x, gfx.y = 0, LW * 0.5
gfx.set(1, 1, 1)
gfx.a = 0.80

gfx.dest = 127; gfx.mode = 6
gfx.drawstr("...Rotated Text...")

ang = math.rad(270)

function main()
    key = gfx.getchar()
    
    gfx.dest = -1; gfx.mode = 6
    gfx.x, gfx.y = 200, 200 
    
    gfx.blit(127, 1, ang,   0, 0, LW, LW,   100, 100, LW, LW)
    gfx.update()     
    
    if key ~= -1 and key ~= 27 then reaper.defer(main) end

    ang = ang + 0.01
    if ang > math.rad(360) then ang = 0 end
end

main()
It's obviously not ideal because the src/dst rectangles are much larger than what you want (width, height instead of width, width as I used).

<previous edit removed>
But... why that doesn't work when you swap width/height at the destination, as in your example, I don't know.
__________________
Return of the Dub Cadet - https://open.spotify.com/album/2t98A...lQ&dl_branch=1

Last edited by RobU; 08-02-2018 at 05:52 AM.
RobU is offline   Reply With Quote
Old 08-02-2018, 09:56 AM   #3
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,681
Default

Yes, you'd think that it should work, shouldn't it?

But, thank you for the code snippet- the key seems to be having a square image size, slightly bigger than the string width. I tried it with a few examples and am making some progress. However:
(a) I turned on "Blend" mode for gfx.mode, otherwise I got the black background from the buffer. (As in the screenshot below.)

(b) how do I initialise the off-screen buffer; sometimes when I changed the text it seemed to have kept the image of the previous text in the buffer

(c) the rotation degraded the quality of the text characters

(d) short strings (or is it lower-case strings?) (e.g. "two") had their bottoms chopped off

This shows a string with 0 rotation, 270 rotation and my idea of the buffer with the transformation shown. Given that it is a straight-forward 90 degree transform, maybe there is a better way.

__________________
DarkStar ... interesting, if true. . . . Inspired by ...

Last edited by DarkStar; 08-02-2018 at 10:05 AM.
DarkStar is offline   Reply With Quote
Old 08-02-2018, 11:10 AM   #4
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

you need to "clear" the buffer if you are going to reuse it.

This is undocumented, but (iirc) the way to do that is to set the image dimensions to a negative number.

i.e

gfx.setimgdim(127, -1, -1);

then resize it to what you need. in doing that, you clear the buffer back to alpha.

Last edited by James HE; 08-02-2018 at 11:15 AM.
James HE is offline   Reply With Quote
Old 08-02-2018, 01:08 PM   #5
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

I think any resize will do it; -1,-1 might just be a convention to make it obvious.

Quote:
Resize image referenced by index 0..1024-1, width and height must be 0-2048. The contents of the image will be undefined after the resize.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 08-02-2018, 01:14 PM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Disclaimer - pure conjecture:

When it rotates the image it's still got that buffer's dimensions to work with, so a 128x64 image can't be rotated 90 degrees without losing half of it - thus, needing a 128x128 buffer.

You could always use another buffer in between - draw the text to a 128x128 buffer, rotational blit it to another 128x128 buffer so you have the whole thing, then blit from there to the main buffer and specify a source rectangle of 64x128.

----

Completely unrelated, but worth remembering in case you haven't run into it yet - if you draw text straight into an empty buffer and then blit it onto a background, the edges will look shitty because they were antialiased against empty pixels. It's usually a good idea to draw a solid background the same dimensions as the text + a couple of pixels to catch the antialiasing.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 08-03-2018, 04:44 AM   #7
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

Quote:
Originally Posted by Lokasenna View Post
I think any resize will do it; -1,-1 might just be a convention to make it obvious.

Unless something changed internally, negative resizing is the only way to get the buffer to go back to the alpha channel. Otherwise, things just get stuck in there. I can't seem to find the thread where MPL and I figured this out - it might have just been him - I can't remember.. lol!
James HE is offline   Reply With Quote
Old 11-11-2019, 03:56 AM   #8
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,681
Default

Revisiting this one...

It looks to me that any blit rotation without any shape distortion needs a square source and target. Is that correct?

Or, what is the best way to achieve the transformation of the text and its background:



I was hoping that the gfx_blit() above would do it, but no.
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 11-15-2019, 09:09 AM   #9
DarkStar
Human being with feelings
 
DarkStar's Avatar
 
Join Date: May 2006
Location: Surrey, UK
Posts: 19,681
Default

Anyone ... ?
__________________
DarkStar ... interesting, if true. . . . Inspired by ...
DarkStar is offline   Reply With Quote
Old 11-15-2019, 09:33 AM   #10
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

I played with it a bit for an image module in my GUI, and I think you're right - blitting and rotating a rectangular source ends up chopping things off.

One workaround might be to blit the original source into the middle of a square buffer and then blit+rotate from there to where you want it.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 10-30-2020, 11:21 PM   #11
woodslanding
Human being with feelings
 
woodslanding's Avatar
 
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
Default

Did anyone try transformblit with text?

I tried just putting it in after the drawstr call in the draw method of a Scythe component, but it obliterates the text and the image behind it. I tried adding a drawstr call to Justin's code, but that didn't do anything either. How would I rotate the text without also rotating the background image?

I really don't understand how gfx works at a basic level, I think...
__________________
eric moon
Very Stable Genius
https://gogolab.com/
woodslanding is offline   Reply With Quote
Old 12-17-2020, 12:38 PM   #12
woodslanding
Human being with feelings
 
woodslanding's Avatar
 
Join Date: Mar 2007
Location: Denver, CO
Posts: 633
Default Transformblit working for text

The nice thing about transformblit is that you can make the background rectangle the exact right size... the downside is that drawing non-rotated text is a completely different process.

I'm starting to get my head around gfx. I think the important thing to realize is that when drawing offscreen, you are referencing everything against 0,0. Then when you draw to screen you put it where you want it. I didn't really get that before, and nothing makes sense if you are always thinking about screen coordinates.

Transformblit is pretty fun. I got some wild effects before I figured out what's what.

Code:
------------------------------------------------------
--[[gfx.transformblit(127, -- source image
0,h, h,w, -- output x/y/w/h
2,2, -- 2x2 table below:
{  -- gfx.transformblit takes a table of coordinates
    w,0, -- source coordinates of top left
    h,w, -- source coordinates of top right
    0,0, -- source coordinates of bottom left
    0,h,-- source coordinates of bottom right
}
)--]]
-------------------------------------------------------
 --if center is true, then offsets are +- % of available space.  If not, offsets are pixels from lower left
function rotate_text(text, x, y, w, h, center, offsX, offsY )
    gfx.x = 0
    gfx.y = 0
    save_gfxr = gfx.r; save_gfxg = gfx.g; save_gfxb = gfx.b  --text color

    gfx.r = 30/256; gfx.g = 30/256; gfx.b = 70/256  -- background colour, for the off-screen buffer
    strW, strH = gfx.measurestr(text)  -- in pixels
    playX, playY = (h - strW)/2, (w - strH)/2
    if center then
      xpos = playX + (playX * offsX)
      ypos = playY + (playY * offsY)
    else
      xpos = offsY
      ypos = offsX
    end

    gfx.dest=127;                   -- draw to off-screen buffer
    gfx.setimgdim(127, -1, -1)      -- clear the buffer
    gfx.setimgdim(127, h + 1, w)  -- sets its size.  For some reason it's a pixel small in one direction
    gfx.rect(0,0, h, w)           -- set the bg colour, for improved anti-aliasing

    gfx.a = 1
    gfx.r = save_gfxr; gfx.g = save_gfxg; gfx.b = save_gfxb -- set the text colour

    gfx.x = xpos
    gfx.y = ypos

    gfx.printf("%s", text)

    gfx.dest=-1;                           -- switch back to on-screen
    gfx.mode = 0 +1-1 + 2 +4               -- blend mode (1) deactivated, disable source alpha (2),
    gfx.transformblit(127,  x,y, w, h, 2,2,  { h,0,  h,w,  0,0,  0,w, } )

end

function loop()
    x = 10
    y = 30
    w = 80
    h = 150
    adjX, adjY = 0,4
    gfx.x = 0
    gfx.y = 0
    gfx.rect(x,y,w,h)  --white reference rectangle
    rotate_text('hello world',x,y,w,h, false, adjX,adjY)
    if gfx.getchar() >= 0 then
      reaper.defer(loop)
    end
end

gfx.init("", 400, 300)
gfx.setfont(1, "sans-serif", 24)
gfx.r, gfx.g, gfx.b = 1, 1, 1
loop()
__________________
eric moon
Very Stable Genius
https://gogolab.com/
woodslanding is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 05:42 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.