152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod/* 252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * Copyright © 2012 Google, Inc. 352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * 452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * This is part of HarfBuzz, a text shaping library. 552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * 652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * Permission is hereby granted, without written agreement and without 752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * software and its documentation for any purpose, provided that the 952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * above copyright notice and the following two paragraphs appear in 1052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * all copies of this software. 1152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * 1252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * DAMAGE. 1752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * 1852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * 2452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * Google Author(s): Behdad Esfahbod 2552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod */ 2652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 2752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod#include "helper-cairo-ansi.hh" 2852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod#include "options.hh" 2952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 3052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod#include "ansi-print.hh" 3152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 3252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 3352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbodcairo_status_t 3452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbodhelper_cairo_surface_write_to_ansi_stream (cairo_surface_t *surface, 3552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_write_func_t write_func, 3652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod void *closure) 3752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod{ 3852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod unsigned int width = cairo_image_surface_get_width (surface); 3952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod unsigned int height = cairo_image_surface_get_height (surface); 4052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) { 4152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_surface_t *new_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); 4252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_t *cr = cairo_create (new_surface); 4352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_A8) { 4452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_set_source_rgb (cr, 0., 0., 0.); 4552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_paint (cr); 4652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_set_source_rgb (cr, 1., 1., 1.); 4752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_mask_surface (cr, surface, 0, 0); 4852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod } else { 4952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_set_source_rgb (cr, 1., 1., 1.); 5052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_paint (cr); 5152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_set_source_surface (cr, surface, 0, 0); 5252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_paint (cr); 5352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod } 5452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_destroy (cr); 5552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod surface = new_surface; 5652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod } else 5752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_surface_reference (surface); 5852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 5952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod unsigned int stride = cairo_image_surface_get_stride (surface); 60c77d1ade6898cea161f0709c5c5a912e14aff951Behdad Esfahbod const uint32_t *data = (uint32_t *) (void *) cairo_image_surface_get_data (surface); 6152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 6252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod /* We don't have rows to spare on the terminal window... 6352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod * Find the tight image top/bottom and only print in between. */ 6452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 6552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod /* Use corner color as background color. */ 6680f77282264afb1356351024b1f062b2824bba3bBehdad Esfahbod uint32_t bg_color = data ? * (uint32_t *) data : 0; 6752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 6852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod /* Drop first row while empty */ 6980f77282264afb1356351024b1f062b2824bba3bBehdad Esfahbod while (height) 7052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod { 7152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod unsigned int i; 7252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod for (i = 0; i < width; i++) 7352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (data[i] != bg_color) 7452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod break; 7552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (i < width) 7652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod break; 7752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod data += stride / 4; 7852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod height--; 7952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod } 8052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 8152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod /* Drop last row while empty */ 8252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod unsigned int orig_height = height; 8352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod while (height) 8452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod { 8552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod const uint32_t *row = data + (height - 1) * stride / 4; 8652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod unsigned int i; 8752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod for (i = 0; i < width; i++) 8852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (row[i] != bg_color) 8952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod break; 9052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (i < width) 9152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod break; 9252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod height--; 9352e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod } 9452e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (height < orig_height) 9552e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod height++; /* Add one last blank row for padding. */ 9652e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 9752e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod if (width && height) 9852e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod ansi_print_image_rgb24 (data, width, height, stride / 4); 9952e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod 10052e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod cairo_surface_destroy (surface); 10152e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod return CAIRO_STATUS_SUCCESS; 10252e7b1424a3613122e9ca30879298df42733acdaBehdad Esfahbod} 103