Behdad Esfahbod | 52e7b14 | 2012-05-13 02:02:58 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright © 2012 Google, Inc. |
| 3 | * |
| 4 | * This is part of HarfBuzz, a text shaping library. |
| 5 | * |
| 6 | * Permission is hereby granted, without written agreement and without |
| 7 | * license or royalty fees, to use, copy, modify, and distribute this |
| 8 | * software and its documentation for any purpose, provided that the |
| 9 | * above copyright notice and the following two paragraphs appear in |
| 10 | * all copies of this software. |
| 11 | * |
| 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
| 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
| 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
| 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
| 16 | * DAMAGE. |
| 17 | * |
| 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
| 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
| 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
| 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
| 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 23 | * |
| 24 | * Google Author(s): Behdad Esfahbod |
| 25 | */ |
| 26 | |
| 27 | #include "helper-cairo-ansi.hh" |
| 28 | #include "options.hh" |
| 29 | |
| 30 | #include "ansi-print.hh" |
| 31 | |
| 32 | |
| 33 | cairo_status_t |
| 34 | helper_cairo_surface_write_to_ansi_stream (cairo_surface_t *surface, |
| 35 | cairo_write_func_t write_func, |
| 36 | void *closure) |
| 37 | { |
| 38 | unsigned int width = cairo_image_surface_get_width (surface); |
| 39 | unsigned int height = cairo_image_surface_get_height (surface); |
| 40 | if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) { |
| 41 | cairo_surface_t *new_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); |
| 42 | cairo_t *cr = cairo_create (new_surface); |
| 43 | if (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_A8) { |
| 44 | cairo_set_source_rgb (cr, 0., 0., 0.); |
| 45 | cairo_paint (cr); |
| 46 | cairo_set_source_rgb (cr, 1., 1., 1.); |
| 47 | cairo_mask_surface (cr, surface, 0, 0); |
| 48 | } else { |
| 49 | cairo_set_source_rgb (cr, 1., 1., 1.); |
| 50 | cairo_paint (cr); |
| 51 | cairo_set_source_surface (cr, surface, 0, 0); |
| 52 | cairo_paint (cr); |
| 53 | } |
| 54 | cairo_destroy (cr); |
| 55 | surface = new_surface; |
| 56 | } else |
| 57 | cairo_surface_reference (surface); |
| 58 | |
| 59 | unsigned int stride = cairo_image_surface_get_stride (surface); |
Behdad Esfahbod | c77d1ad | 2013-10-27 23:52:26 +0100 | [diff] [blame] | 60 | const uint32_t *data = (uint32_t *) (void *) cairo_image_surface_get_data (surface); |
Behdad Esfahbod | 52e7b14 | 2012-05-13 02:02:58 +0200 | [diff] [blame] | 61 | |
| 62 | /* We don't have rows to spare on the terminal window... |
| 63 | * Find the tight image top/bottom and only print in between. */ |
| 64 | |
| 65 | /* Use corner color as background color. */ |
Behdad Esfahbod | 80f7728 | 2014-09-25 17:59:46 +0300 | [diff] [blame] | 66 | uint32_t bg_color = data ? * (uint32_t *) data : 0; |
Behdad Esfahbod | 52e7b14 | 2012-05-13 02:02:58 +0200 | [diff] [blame] | 67 | |
| 68 | /* Drop first row while empty */ |
Behdad Esfahbod | 80f7728 | 2014-09-25 17:59:46 +0300 | [diff] [blame] | 69 | while (height) |
Behdad Esfahbod | 52e7b14 | 2012-05-13 02:02:58 +0200 | [diff] [blame] | 70 | { |
| 71 | unsigned int i; |
| 72 | for (i = 0; i < width; i++) |
| 73 | if (data[i] != bg_color) |
| 74 | break; |
| 75 | if (i < width) |
| 76 | break; |
| 77 | data += stride / 4; |
| 78 | height--; |
| 79 | } |
| 80 | |
| 81 | /* Drop last row while empty */ |
| 82 | unsigned int orig_height = height; |
| 83 | while (height) |
| 84 | { |
| 85 | const uint32_t *row = data + (height - 1) * stride / 4; |
| 86 | unsigned int i; |
| 87 | for (i = 0; i < width; i++) |
| 88 | if (row[i] != bg_color) |
| 89 | break; |
| 90 | if (i < width) |
| 91 | break; |
| 92 | height--; |
| 93 | } |
| 94 | if (height < orig_height) |
| 95 | height++; /* Add one last blank row for padding. */ |
| 96 | |
| 97 | if (width && height) |
| 98 | ansi_print_image_rgb24 (data, width, height, stride / 4); |
| 99 | |
| 100 | cairo_surface_destroy (surface); |
| 101 | return CAIRO_STATUS_SUCCESS; |
| 102 | } |