]> git.neil.brown.name Git - edlib.git/commitdiff
Draw:image - move mode information from num to str2
authorNeilBrown <neil@brown.name>
Fri, 22 Sep 2023 04:40:59 +0000 (14:40 +1000)
committerNeilBrown <neil@brown.name>
Wed, 27 Sep 2023 06:00:03 +0000 (16:00 +1000)
The information about whether the images should be stretch, centered, or
aligned top/bot/left/right is now in 'str2', leaving number free to be a
number.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/Calls
display-ncurses.c
display-x11-xcb.c
lib-renderline.c
python/display-pygtk.py
python/render-present.py
render-lines.c

index db1948772fe2319d2aaadf4d42bc9cc2ab9c2e59..a35e7a135db27c9f3882261384c75fe7751fae20 100644 (file)
--- a/DOC/Calls
+++ b/DOC/Calls
@@ -120,14 +120,15 @@ Draw an image on the pane (or ancestor which as been cleared).
 - str1 identifies the images, either "file:FILENAME" or "comm:COMMAND".
   If "comm:" the command is run and result should be returned as 'bytes'
   (comm2 called with ->str1 as array of bytes, ->num1 as length).
-- num is the 'or' of the following bit flags:
-   - 16 stretch image to exactly fit pane.  If set, lower bits are ignored.
-  Otherwise image will fill the pane in one dimension, and be positioning
-  left/centre/right in the other.
-    - 1 centre horizontally
-    - 2 right-align horizontally
-    - 4 centre vertically
-    - 8 bottom-align vertially
+- str2 contains 'mode' information.
+      - By default the image is placed centrally in the pane
+        and scaled to use either fully height or fully width.
+      - Various letters modify this:
+           'S' - stretch to use full height *and* full width
+           'L' - place on left if full width isn't used
+           'R' - place on right if full width isn't used
+           'T' - place at top if full height isn't used
+           'B' - place at bottom if full height isn't used.
 - (x,y) gives a number of rows and cols to overlay on the image for
     the purpose of cursor positioning.  If these are positive and
     p->cx,cy are not negative, draw a cursor at p->cx,cy highlighting
index 5449a0846f7e1e489caaa6587d3d5fdf7dd697a1..34d22eab5d201a1188414fcc2a40a563f2e8b5f1 100644 (file)
@@ -1000,12 +1000,16 @@ DEF_CMD(nc_draw_image)
        /* 'str' identifies the image. Options are:
         *     file:filename  - load file from fs
         *     comm:command   - run command collecting bytes
-        * 'num' is '16' if image should be stretched to fill pane
-        * Otherwise it is the 'or' of
-        *   0,1,2 for left/middle/right in x direction
-        *   0,4,8 for top/middle/bottom in y direction
-        * only one of these can be used as image will fill pane
-        * in other direction.
+        * 'str2' container 'mode' information.
+        *     By default the image is placed centrally in the pane
+        *     and scaled to use either fully height or fully width.
+        *     Various letters modify this:
+        *     'S' - stretch to use full height *and* full width
+        *     'L' - place on left if full width isn't used
+        *     'R' - place on right if full width isn't used
+        *     'T' - place at top if full height isn't used
+        *     'B' - place at bottom if full height isn't used.
+        *
         * If 'x' and 'y' are both positive, draw cursor box at
         * p->cx, p->cy of a size so that 'x' will fit across and
         * 'y' will fit down.
@@ -1013,8 +1017,8 @@ DEF_CMD(nc_draw_image)
        struct pane *p = ci->home;
        struct display_data *dd = p->data;
        int x = 0, y = 0;
-       bool stretch = ci->num & 16;
-       int pos = ci->num;
+       const char *mode = ci->str2 ?: "";
+       bool stretch = strchr(mode, 'S');
        int w = ci->focus->w, h = ci->focus->h * 2;
        int cx = -1, cy = -1;
        MagickBooleanType status;
@@ -1060,23 +1064,22 @@ DEF_CMD(nc_draw_image)
                if (iw * h > ih * w) {
                        /* Image is wider than space, use less height */
                        ih = ih * w / iw;
-                       switch(pos & (8+4)) {
-                       case 4: /* center */
-                               y = (h - ih) / 2; break;
-                       case 8: /* bottom */
-                               y = h - ih; break;
-                       }
+                       if (strchr(mode, 'B'))
+                               /* bottom */
+                               y = h - ih;
+                       else if (!strchr(mode, 'T'))
+                               /* center */
+                               y = (h - ih) / 2;
                        /* Keep 'h' even! */
                        h = ((ih+1)/2) * 2;
                } else {
                        /* image is too tall, use less width */
                        iw = iw * h / ih;
-                       switch (pos & (1+2)) {
-                       case 1: /* center */
-                               x = (w - iw) / 2; break;
-                       case 2: /* right */
-                               x = w - iw ; break;
-                       }
+                       if (strchr(mode, 'R'))
+                               /* right */
+                               x = w - iw;
+                       else if (!strchr(mode, 'L'))
+                               x = (w - iw) / 2;
                        w = iw;
                }
        }
index 55e631fa086bafa4e1b9cd620417b5d2ef946bd8..22c75c993dee4cb4e3700ef65d9c18a7bdc75140 100644 (file)
@@ -810,19 +810,23 @@ DEF_CMD(xcb_draw_image)
        /* 'str' identifies the image. Options are:
         *     file:filename  - load file from fs
         *     comm:command   - run command collecting bytes
-        * 'num' is '16' if image should be stretched to fill pane
-        * Otherwise it is the 'or' of
-        *   0,1,2 for left/middle/right in x direction
-        *   0,4,8 for top/middle/bottom in y direction
-        * only one of these can be used as image will fill pane
-        * in other direction.
+        * 'str2' container 'mode' information.
+        *     By default the image is placed centrally in the pane
+        *     and scaled to use either fully height or fully width.
+        *     Various letters modify this:
+        *     'S' - stretch to use full height *and* full width
+        *     'L' - place on left if full width isn't used
+        *     'R' - place on right if full width isn't used
+        *     'T' - place at top if full height isn't used
+        *     'B' - place at bottom if full height isn't used.
+        *
         * If 'x' and 'y' are both positive, draw cursor box at
         * p->cx, p->cy of a size so that 'x' will fit across and
         * 'y' will fit down.
         */
        struct xcb_data *xd = ci->home->data;
-       bool stretch = ci->num & 16;
-       int pos = ci->num;
+       const char *mode = ci->str2 ?: "";
+       bool stretch = strchr(mode, 'S');
        int w = ci->focus->w, h = ci->focus->h;
        int x = 0, y = 0;
        int xo, yo;
@@ -880,22 +884,21 @@ DEF_CMD(xcb_draw_image)
                if (iw * h > ih * w) {
                        /* Image is wider than space, use less height */
                        ih = ih * w / iw;
-                       switch(pos & (8+4)) {
-                       case 4: /* center */
-                               y = (h - ih) / 2; break;
-                       case 8: /* bottom */
-                               y = h - ih; break;
-                       }
+                       if (strchr(mode, 'B'))
+                               /* bottom */
+                               y = h - ih;
+                       else if (!strchr(mode, 'T'))
+                               /* center */
+                               y = (h - ih) / 2;
                        h = ih;
                } else {
                        /* image is too tall, use less width */
                        iw = iw * h / ih;
-                       switch (pos & (1+2)) {
-                       case 1: /* center */
-                               x = (w - iw) / 2; break;
-                       case 2: /* right */
-                               x = w - iw ; break;
-                       }
+                       if (strchr(mode, 'R'))
+                               /* right */
+                               x = w - iw;
+                       else if (!strchr(mode, 'L'))
+                               x = (w - iw) / 2;
                        w = iw;
                }
        }
index da3c99cb9ecd16e4b107719d650e3f4b2f9d0d99..3fcca5e26478fd7b181d9811da008ad17f695324 100644 (file)
@@ -1130,7 +1130,7 @@ static int render_image(struct pane *p safe, struct pane *focus safe,
        }
 
        if (fname && dodraw)
-               home_call(focus, "Draw:image", p, 5, NULL, fname,
+               home_call(focus, "Draw:image", p, 0, NULL, fname,
                          0, NULL, NULL, cols, rows);
 
        free(fname);
index fa9499cfa949c9f7598d7415d0479c065bb83bb9..3c62c5287460d52ec0387c95d21670ad1a540b29 100644 (file)
@@ -276,33 +276,37 @@ class EdDisplay(edlib.Pane):
 
         return True
 
-    def handle_image(self, key, num, focus, str, xy, **a):
+    def handle_image(self, key, focus, str1, str2, xy, **a):
         "handle:Draw:image"
         self.damaged(edlib.DAMAGED_POSTORDER)
-        # 'str' identifies the image. Options are:
+        # 'str1' identifies the image. Options are:
         #     file:filename  - load file from fs
         #     comm:command   - run command collecting bytes
-        # 'num' is '16' if image should be stretched to fill pane
-        # otherwise it is 'or' of
-        #   0,1,2 for left/middle/right in x direction
-        #   0,4,8 for top/middle/bottom in y direction
-        # only one of these can be used as image will fill pane
-        # in other direction.
+        # 'str2' contains 'mode' information.
+        #   - By default the image is placed centrally in the pane
+        #     and scaled to use either fully height or fully width.
+        #   - Various letters modify this:
+        #       'S' - stretch to use full height *and* full width
+        #       'L' - place on left if full width isn't used
+        #       'R' - place on right if full width isn't used
+        #       'T' - place at top if full height isn't used
+        #       'B' - place at bottom if full height isn't used.
+        #
         # xy gives a number of rows and cols to overlay on the image
         # for the purpose of cursor positioning.  If these are positive
         # and focus.cx,cy are not negative, draw a cursor at cx,cy
         # highlighting the relevant cell.
-        if not str:
+        if not str1:
             return edlib.Enoarg
-        stretch = num & 16
-        pos = num
+        mode = str2 if str2 else ""
+        stretch = 'S' in mode
         w, h = focus.w, focus.h
         x, y = 0, 0
         try:
-            if str.startswith("file:"):
-                pb = GdkPixbuf.Pixbuf.new_from_file(str[5:])
-            elif str.startswith("comm:"):
-                img = focus.call(str[5:], ret='bytes')
+            if str1.startswith("file:"):
+                pb = GdkPixbuf.Pixbuf.new_from_file(str1[5:])
+            elif str1.startswith("comm:"):
+                img = focus.call(str1[5:], ret='bytes')
                 io = Gio.MemoryInputStream.new_from_data(img)
                 pb = GdkPixbuf.Pixbuf.new_from_stream(io)
             else:
@@ -316,18 +320,18 @@ class EdDisplay(edlib.Pane):
             if pb.get_width() * h > pb.get_height() * w:
                 # image is wider than space, reduce height
                 h2 = pb.get_height() * w / pb.get_width()
-                if pos & 12 == 4:
-                    y = (h - h2) / 2
-                if pos & 12 == 8:
+                if 'B' in mode:
                     y = h - h2
+                elif 'T' not in mode:
+                    y = (h - h2) / 2
                 h = h2
             else:
                 # image is too tall, reduce width
                 w2 = pb.get_width() * h / pb.get_height()
-                if pos & 3 == 1:
-                    x = (w - w2) / 2
-                if pos & 3 == 2:
+                if 'R' in mode:
                     x = w - w2
+                elif 'L' not in mode:
+                    x = (w - w2) / 2
                 w = w2
         scale = pb.scale_simple(w, h, GdkPixbuf.InterpType.HYPER)
         pm, xo, yo, pbg = self.find_pixmap(focus, True)
index 287b9addbcbcc82e53eb84235a288cc643d1815b..eeed49111afa04189f94e8e473c0958e7048e28e 100644 (file)
@@ -469,11 +469,11 @@ class PresenterPane(edlib.Pane):
             if c[:6] == 'color:':
                 rv = focus.call('Draw:clear', 'bg:' + c[6:])
             if s and c[:14] == "image-stretch:":
-                rv = focus.call('Draw:image', 16, "file:" + self.pathto(c[14:]))
+                rv = focus.call('Draw:image', "file:" + self.pathto(c[14:]), "S")
             if s and c[:6] == "image:":
-                rv = focus.call('Draw:image', 4+1, "file:" + self.pathto(c[6:])) # centre
+                rv = focus.call('Draw:image', "file:" + self.pathto(c[6:])) # centre
             if s and c[:8] == "overlay:":
-                rv = focus.call('Draw:image', 0+2, "file:" + self.pathto(c[8:])) # top right
+                rv = focus.call('Draw:image', "file:" + self.pathto(c[8:]), "TR") # top right
             if c == "page-local":
                 page = self.find_pages(mark)
                 self.clean_lines(page)
index b2fbce1248e5bdc36f1d4ba56937588dc997a1be..6e5a85e3051faddf84bcfd1fa1fa0b3db082182c 100644 (file)
@@ -909,7 +909,7 @@ static int render(struct mark *pm, struct pane *p safe,
                free(a);
        } else if (strstarts(s, "image:")) {
                home_call(focus, "Draw:clear", p);
-               home_call(focus, "Draw:image", p, 16, NULL, s+6);
+               home_call(focus, "Draw:image", p, 0, NULL, s+6, 0, NULL, "S");
                rl->background_uniform = False;
        } else
                home_call(focus, "Draw:clear", p, 0, NULL, "");