первый
This commit is contained in:
427
lib/wxCairo.cpp
Normal file
427
lib/wxCairo.cpp
Normal file
@ -0,0 +1,427 @@
|
||||
/***************************************************************
|
||||
* Name: wxCairo.cpp
|
||||
* Purpose: Code for Application Frame
|
||||
* Author: Igor I (info@tiptopcity.com)
|
||||
* Created: 2009-05-24
|
||||
* Copyright: Igor I (www.tiptopcity.com)
|
||||
* License:
|
||||
**************************************************************/
|
||||
|
||||
#ifdef WX_PRECOMP
|
||||
#include "wx_pch.h"
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//#include <cairo/cairo-svg.h>
|
||||
//#include <librsvg/rsvg.h>
|
||||
//#include <librsvg/rsvg-cairo.h>
|
||||
#if defined(_WIN32) || defined(_WINDOWS) || defined(_BORLAND) || defined(__BORLANDC__)
|
||||
#include <cairo/cairo-win32.h>
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
//#include <librsvg/rsvg.h>
|
||||
//#include <librsvg/rsvg-cairo.h>
|
||||
//#include <svg_cairo.c>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wxCairo.h"
|
||||
#include "stdTools.h"
|
||||
//#include "wxgui/debug.h"
|
||||
//------------------------------------------------------------------------------
|
||||
struct stdword{
|
||||
std::string str;
|
||||
int width;
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
wxCairo::wxCairo()
|
||||
{
|
||||
glId=0;
|
||||
m_buffer=NULL;
|
||||
m_surface=NULL;
|
||||
m_cr=NULL;
|
||||
m_format = CAIRO_FORMAT_RGB24;
|
||||
m_width=0; m_height=0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
wxCairo::~wxCairo()
|
||||
{
|
||||
if(m_buffer!=NULL) delete m_buffer;
|
||||
if(m_surface!=NULL) cairo_surface_destroy(m_surface);
|
||||
if(m_cr!=NULL) cairo_destroy(m_cr);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned char* wxCairo::CreateBuffer(int width,int height)
|
||||
{
|
||||
if(width!=m_width || m_height!=height)
|
||||
{
|
||||
if(m_buffer!=NULL) delete m_buffer;
|
||||
m_width=width; m_height=height;
|
||||
m_buffer = new unsigned char[width*height*4]; //RGBA
|
||||
memset(m_buffer, 0, width*height*4); //Обнулим массив
|
||||
Init();
|
||||
return m_buffer;
|
||||
}else
|
||||
{
|
||||
memset(m_buffer, 0, width*height*4); //Обнулим(отчистим) массив
|
||||
return m_buffer;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool wxCairo::Init()
|
||||
{
|
||||
if(m_surface!=NULL) cairo_surface_destroy(m_surface);
|
||||
if(m_cr!=NULL) cairo_destroy(m_cr);
|
||||
m_surface = cairo_image_surface_create_for_data(m_buffer, m_format, m_width, m_height, m_width*4);
|
||||
m_cr = cairo_create(m_surface);
|
||||
cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_NONE);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/*void wxCairo::Draw(wxPaintDC& dc)
|
||||
{
|
||||
// Convert from Cairo RGB24 format to wxImage BGR format.
|
||||
unsigned char *dRGB = new unsigned char[m_width*m_height*3];
|
||||
//unsigned char *dA = new unsigned char[m_width*m_height];
|
||||
for(int y=0;y<m_height;y++)
|
||||
{
|
||||
for(int x=0;x<m_width;x++)
|
||||
{
|
||||
dRGB[x*3+y*m_width*3] = m_buffer[x*4+2+y*m_width*4];
|
||||
dRGB[x*3+1+y*m_width*3] = m_buffer[x*4+1+y*m_width*4];
|
||||
dRGB[x*3+2+y*m_width*3] = m_buffer[x*4+y*m_width*4];
|
||||
|
||||
//dA[x*y] = 255;
|
||||
}
|
||||
}
|
||||
// Blit final image to the screen.
|
||||
//wxImage img=wxImage(m_width, m_height, dRGB, dA, true);
|
||||
wxImage img=wxImage(m_width, m_height, dRGB, true);
|
||||
//if(img.HasAlpha())
|
||||
//{
|
||||
wxBitmap m_bitmap(img);
|
||||
dc.DrawBitmap(m_bitmap, 0, 0, true);
|
||||
//}
|
||||
delete dRGB;
|
||||
//delete dA;
|
||||
}*/
|
||||
//------------------------------------------------------------------------------
|
||||
//Нарисуем чтонибудь для примера в текущем буфере
|
||||
bool wxCairo::Test()
|
||||
{
|
||||
// White background.
|
||||
//cairo_set_source_rgb(m_cr, 1.0, 1.0, 1.0);
|
||||
//cairo_rectangle(m_cr, 0, 0, m_width, m_height);
|
||||
//cairo_fill(m_cr);
|
||||
|
||||
//draw stuff
|
||||
cairo_select_font_face(m_cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
|
||||
cairo_set_font_size(m_cr, 32.0);
|
||||
cairo_set_source_rgb(m_cr, 0.0, 0.0, 1.0);
|
||||
cairo_move_to(m_cr, 10.0, 50.0);
|
||||
|
||||
std::string str="Привет мир!";
|
||||
//const wxCharBuffer buff = str.mb_str(wxConvUTF8);
|
||||
cairo_show_text (m_cr, str.c_str());
|
||||
|
||||
//Curve
|
||||
double x=25.6, y=128.0;
|
||||
double x1=102.4, y1=230.4,
|
||||
x2=153.6, y2=25.6,
|
||||
x3=230.4, y3=128.0;
|
||||
|
||||
cairo_move_to (m_cr, x, y);
|
||||
cairo_curve_to (m_cr, x1, y1, x2, y2, x3, y3);
|
||||
|
||||
cairo_set_line_width (m_cr, 10.0);
|
||||
cairo_stroke (m_cr);
|
||||
|
||||
cairo_set_source_rgba (m_cr, 1, 0.2, 0.2, 0.6);
|
||||
cairo_set_line_width (m_cr, 6.0);
|
||||
cairo_move_to (m_cr,x,y); cairo_line_to (m_cr,x1,y1);
|
||||
cairo_move_to (m_cr,x2,y2); cairo_line_to (m_cr,x3,y3);
|
||||
cairo_stroke (m_cr);
|
||||
|
||||
//SVG
|
||||
/*cairo_surface_t *surface;
|
||||
//cairo_t *cr;
|
||||
|
||||
surface = cairo_svg_surface_create("Svg.svg", 390, 60);
|
||||
cr = cairo_create(surface);
|
||||
|
||||
cairo_set_source_rgb(m_cr, 0, 0, 0);
|
||||
cairo_select_font_face (m_cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||
cairo_set_font_size (m_cr, 40.0);
|
||||
|
||||
cairo_move_to(m_cr, 10.0, 50.0);
|
||||
cairo_show_text(m_cr, "Disziplin ist Macht.");
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
//cairo_destroy(cr);*/
|
||||
|
||||
/*double IMAGE_WIDTH = 256;
|
||||
double IMAGE_HEIGHT = 256;
|
||||
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||
cairo_t* cr = cairo_create(surface);
|
||||
cairo_scale(cr, IMAGE_WIDTH, IMAGE_HEIGHT);
|
||||
svg_cairo_t* svgc;
|
||||
svg_cairo_create(&svgc);
|
||||
gtk_init(&argc, &argv); // 1) doesn't work
|
||||
svg_cairo_parse(svgc, "data/home.svg");
|
||||
// gtk_init(&argc, &argv); // 2) works
|
||||
unsigned w, h;
|
||||
svg_cairo_get_size(svgc, &w, &h);
|
||||
cairo_scale(cr, 1.0 / w, 1.0 / h);
|
||||
svg_cairo_render(svgc, cr);
|
||||
svg_cairo_destroy(svgc);
|
||||
cairo_surface_write_to_png(surface, "out.png");
|
||||
cairo_destroy(cr);
|
||||
cairo_surface_destroy(surface);
|
||||
return 0;*/
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::MoveTo(double x, double y)
|
||||
{
|
||||
cairo_move_to(m_cr,x,y);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::LineTo(double x, double y)
|
||||
//void wxCairo::LineTo(double y, double x)
|
||||
{
|
||||
cairo_line_to(m_cr,x,y);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::SetLineWidth(double width)
|
||||
{
|
||||
cairo_set_line_width(m_cr, width);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::ShowText(std::wstring& str)
|
||||
{
|
||||
std::string utf8=convUTF16ToUTF8(str);
|
||||
cairo_show_text (m_cr, utf8.c_str());
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::SetSourceRGBA(double red, double green, double blue, double alpha)
|
||||
{
|
||||
cairo_set_source_rgba(m_cr, red, green, blue, alpha);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::SetSourceRGB(double red, double green, double blue)
|
||||
{ cairo_set_source_rgb(m_cr, red, green, blue);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::Rectangle (double x, double y, double width, double height)
|
||||
{ cairo_rectangle (m_cr, x, y, width, height);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//Не рисовать то что не входит в последний геом объект
|
||||
void wxCairo::Clip()
|
||||
{ cairo_clip(m_cr);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::ResetClip()
|
||||
{ cairo_reset_clip(m_cr);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::Fill()
|
||||
{ cairo_fill(m_cr);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//Обводка
|
||||
//Операция cairo_stroke() применяет виртуальный карандаш вдоль контура.Это позволяет источнику передать через маску тонкую(или толстую) линию вдоль контура, в соответствие с карандашной толщиной линии, стилем точек, и наконечниками линии.
|
||||
void wxCairo::Stroke()
|
||||
{ cairo_stroke(m_cr);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//Преобразовать рисунок в битовый массив
|
||||
void wxCairo::toBitArray(unsigned char* bitArray)
|
||||
{
|
||||
int pos = 0;
|
||||
for (int y = 0; y<m_height; y++)
|
||||
{
|
||||
for (int x = 0; x<m_width; x++)
|
||||
{
|
||||
unsigned char r = m_buffer[x * 4 + 2 + y*m_width * 4];
|
||||
unsigned char g = m_buffer[x * 4 + 1 + y*m_width * 4];
|
||||
unsigned char b = m_buffer[x * 4 + y*m_width * 4];
|
||||
unsigned char px = (r + g + b) / 3.0f;
|
||||
|
||||
int posB=floor(pos / 8.0f); //Номер байта
|
||||
|
||||
if (px < 127) //Чёрный это 1
|
||||
{
|
||||
setBit(&bitArray[posB], pos - posB * 8, true);
|
||||
//
|
||||
}else //Белый это 0
|
||||
{
|
||||
setBit(&bitArray[posB], pos - posB * 8, false);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::setBit(unsigned char *mas, const unsigned char pos, bool val)
|
||||
{
|
||||
unsigned char mask = 128;
|
||||
unsigned char loc = pos / 8;
|
||||
mask = mask >> (pos - loc * 8);
|
||||
if (val) mas[loc] = mas[loc] | mask;
|
||||
else
|
||||
{
|
||||
mask = ~mask; //Отрицание
|
||||
mas[loc] = mas[loc] & mask;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::setFontface(std::string family,bool slant,bool weight)
|
||||
{
|
||||
cairo_font_slant_t s;
|
||||
if (slant) s = CAIRO_FONT_SLANT_ITALIC; else s = CAIRO_FONT_SLANT_NORMAL;
|
||||
cairo_font_weight_t w;
|
||||
if (weight) w = CAIRO_FONT_WEIGHT_BOLD; else w = CAIRO_FONT_WEIGHT_NORMAL;
|
||||
|
||||
cairo_select_font_face(m_cr,family.c_str(),s,w);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::setFontface(const char *family, cairo_font_slant_t slant, cairo_font_weight_t weight)
|
||||
{
|
||||
cairo_select_font_face(m_cr, family, slant, weight);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//the new font size, in user space units
|
||||
void wxCairo::setFontSize(double size)
|
||||
{
|
||||
cairo_set_font_size(m_cr,size);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void wxCairo::seveToPNG(std::string filePath)
|
||||
{
|
||||
cairo_surface_write_to_png(m_surface, filePath.c_str());
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//Ширина текста в пикселях
|
||||
double wxCairo::getTextWidth(std::wstring& str)
|
||||
{
|
||||
std::string utf8 = convUTF16ToUTF8(str);
|
||||
cairo_text_extents_t ext;
|
||||
cairo_text_extents(m_cr, utf8.c_str(), &ext);
|
||||
return ext.width;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//Высота текста в пикселях
|
||||
double wxCairo::getTextHeight(std::wstring& str)
|
||||
{
|
||||
std::string utf8 = convUTF16ToUTF8(str);
|
||||
cairo_text_extents_t ext;
|
||||
cairo_text_extents(m_cr, utf8.c_str(), &ext);
|
||||
return ext.height;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//Вывести текст по центру области
|
||||
void wxCairo::ShowTextCenter(std::wstring& str, int xStart, int xEnd, int y)
|
||||
{
|
||||
std::string utf8 = convUTF16ToUTF8(str);
|
||||
|
||||
cairo_text_extents_t ext;
|
||||
cairo_text_extents(m_cr, utf8.c_str(), &ext);
|
||||
|
||||
ext.width = xStart + (((xEnd - xStart) / 2.0f) - (ext.width / 2.0f));
|
||||
cairo_move_to(m_cr, ext.width, y);
|
||||
|
||||
cairo_show_text(m_cr, utf8.c_str());
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//Вывести текст с переносом на следующую строку с выравниванием по словам, высота символов однирна
|
||||
//xStart начало для вычисления центра
|
||||
//xEnd конец для вычисления центра
|
||||
//y высота
|
||||
void wxCairo::ShowTextBR(std::wstring& str, int xStart, int xEnd, int y)
|
||||
{
|
||||
/*stdword line;
|
||||
std::vector<stdword> parts;
|
||||
|
||||
int maxH=0;
|
||||
std::vector<std::wstring> array =split(str,L' ');
|
||||
for (std::vector<std::wstring>::iterator it = array.begin() ; it != array.end(); ++it)
|
||||
{
|
||||
std::wstring s=*it;
|
||||
line.word = convUTF16ToUTF8(s);
|
||||
cairo_text_extents(m_cr, line.word.c_str(), &line.ext);
|
||||
line.ext.width+=line.ext.width/s.length(); //Так как пробел почемуто обрезается при расчёте ширины
|
||||
parts.push_back(line);
|
||||
if(maxH<line.ext.height) maxH=line.ext.height;
|
||||
}
|
||||
|
||||
int w=xStart;
|
||||
for (std::vector<stdword>::iterator it = parts.begin() ; it != parts.end(); ++it)
|
||||
{
|
||||
line=*it;
|
||||
if(w+line.ext.width<xEnd)
|
||||
{
|
||||
cairo_move_to(m_cr, w, y);
|
||||
w+=line.ext.width;
|
||||
}else
|
||||
{
|
||||
w=xStart;
|
||||
y+=maxH;
|
||||
cairo_move_to(m_cr, w, y);
|
||||
w+=line.ext.width;
|
||||
}
|
||||
cairo_show_text(m_cr, line.word.c_str());
|
||||
}*/
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
//Вывести текст с переносом на следующую строку с выравниванием по словам, высота символов однирна
|
||||
//xStart начало для вычисления центра
|
||||
//xEnd конец для вычисления центра
|
||||
//y высота
|
||||
void wxCairo::ShowTextCenterBR(std::wstring& str, int xStart, int xEnd, int y)
|
||||
{
|
||||
std::vector<std::wstring> array =split(str,L' '); //Для разбивки на слова
|
||||
int height=0; //Высота символов
|
||||
std::vector<stdword> parts; //Для разбивки на строки
|
||||
|
||||
stdword line;
|
||||
line.width=0;
|
||||
line.str="";
|
||||
for (std::vector<std::wstring>::iterator it = array.begin() ; it != array.end(); ++it)
|
||||
{
|
||||
std::wstring s=*it;
|
||||
std::string word = convUTF16ToUTF8(s);
|
||||
cairo_text_extents_t ext;
|
||||
cairo_text_extents(m_cr, word.c_str(), &ext);
|
||||
ext.width+=ext.width/s.length(); //Так как пробел почемуто обрезается при расчёте ширины
|
||||
if(height<ext.height) height=ext.height; //Высота символов
|
||||
|
||||
if(line.width+ext.width<xEnd-xStart)
|
||||
{
|
||||
line.width+=ext.width;
|
||||
line.str+=word+' ';
|
||||
}else
|
||||
{
|
||||
parts.push_back(line);
|
||||
line.width=0;
|
||||
line.str="";
|
||||
}
|
||||
}
|
||||
parts.push_back(line);
|
||||
|
||||
//Отображаю текст по центру
|
||||
for (std::vector<stdword>::iterator it = parts.begin() ; it != parts.end(); ++it)
|
||||
{
|
||||
stdword line=*it;
|
||||
int width = xStart + (((xEnd - xStart) / 2.0f) - (line.width / 2.0f));
|
||||
cairo_move_to(m_cr, width, y);
|
||||
cairo_show_text(m_cr, line.str.c_str());
|
||||
y+=height;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user