первый

This commit is contained in:
2024-11-01 12:23:13 +05:00
parent 801d9d33fa
commit 0688c46a7e
226 changed files with 162921 additions and 0 deletions

427
lib/wxCairo.cpp Normal file
View 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;
}
}
//------------------------------------------------------------------------------