360 lines
12 KiB
C++
360 lines
12 KiB
C++
/*
|
|
* zkWidget.cpp
|
|
*
|
|
* Created on: Jul 2, 2013
|
|
* Author: yiyu
|
|
* QQ:1036184468
|
|
* Descriptoin:
|
|
|
|
*/
|
|
|
|
#include "zkWidget.h"
|
|
#include <QColor>
|
|
#include <QMessageBox>
|
|
#include <QDebug>
|
|
#include <QFileInfo>
|
|
#include "SysPara.h"
|
|
|
|
zkWidget::zkWidget(QWidget *parent):QWidget(parent){
|
|
memset(pointMap,0,sizeof(pointMap));
|
|
heightPoint = 0;
|
|
widthPoint = 0;
|
|
scale = 16;
|
|
currXpos = 0;
|
|
currYpos = 0;
|
|
modified = false;
|
|
}
|
|
|
|
zkWidget::~zkWidget(){
|
|
|
|
}
|
|
|
|
void zkWidget::paintEvent(QPaintEvent *event){
|
|
QPainter painter(this);
|
|
QRect rect = event->rect();
|
|
int x = (int)(rect.x()/scale);
|
|
int y = (int)(rect.y()/scale);
|
|
int x_ = rect.x() + rect.width();
|
|
int y_ = rect.y() + rect.height();
|
|
int last_x = x_/scale;
|
|
int last_y = y_/scale;
|
|
//qDebug() << "x:" << rect.x() << "y:" << rect.y() << "width:" << rect.width() << "heigh:" << rect.height();
|
|
for(int i = x; i < widthPoint && i <= last_x; i++){
|
|
for(int j = y; j < heightPoint && j <= last_y; j++){
|
|
QPen pen;
|
|
int width = 0;
|
|
if(currXpos == i && currYpos == j){
|
|
width = (scale>4)?2:1;
|
|
pen.setColor(QColor(Qt::red));
|
|
|
|
}
|
|
else {
|
|
width = (scale > 3)?1:0;
|
|
pen.setColor(QColor(Qt::gray));
|
|
}
|
|
pen.setWidth(width);
|
|
painter.setPen(width?pen:Qt::NoPen);
|
|
if(pointMap[i*MAX_PIC_WIDGET_HEIGHT + j]){
|
|
painter.setBrush(QColor(Qt::black));
|
|
}
|
|
else{
|
|
painter.setBrush(QColor(Qt::white));
|
|
}
|
|
painter.drawRect(i*scale + width,j*scale + width,scale - 2*width,scale - 2*width); //
|
|
}
|
|
}
|
|
}
|
|
|
|
void zkWidget::mousePressEvent ( QMouseEvent * event ){
|
|
int x = (int )(event->x()/(scale));
|
|
int y = (int )(event->y()/scale);
|
|
|
|
if(x < widthPoint && y < heightPoint){
|
|
int oriX = currXpos;
|
|
int oriY = currYpos;
|
|
currXpos = x;
|
|
currYpos = y;
|
|
pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = pointMap[x*MAX_PIC_WIDGET_HEIGHT + y]?0:1;
|
|
update(oriX*scale,oriY*scale,scale,scale); //将原来的焦点去掉
|
|
update(x*scale,y*scale,scale,scale);
|
|
modified = true;
|
|
emit picWidgetModify(widthPoint,heightPoint);
|
|
}
|
|
|
|
}
|
|
|
|
void zkWidget::currPositionMove(int shiftX,int shiftY,bool moveAllPic,bool trimPic,bool expandPic)
|
|
{
|
|
if((widthPoint && heightPoint) || expandPic){
|
|
if(moveAllPic){
|
|
shiftX = - shiftX;
|
|
shiftY = -shiftY;
|
|
int init_x = (shiftX < 0)?(widthPoint - 1):0;
|
|
int end_x = (shiftX >= 0)?(widthPoint):-1;
|
|
int step_x = (shiftX < 0)?-1:1;
|
|
int init_y = (shiftY < 0)?(heightPoint - 1):0;
|
|
int end_y = (shiftY >= 0)?(heightPoint):- 1;
|
|
int step_y = (shiftY < 0)?-1:1;
|
|
for(int x = init_x; x != end_x; x+= step_x){
|
|
for(int y = init_y; y != end_y; y+= step_y){
|
|
int new_x = x + shiftX;
|
|
int new_y = y + shiftY;
|
|
if(new_x < 0 || new_x >= widthPoint || new_y < 0 || new_y >= heightPoint){
|
|
//pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = trueColorEnable?backGround.rgba():0xffffffff;
|
|
pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = 0x00000000;
|
|
}
|
|
else
|
|
pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = pointMap[new_x*MAX_PIC_WIDGET_HEIGHT + new_y];
|
|
}
|
|
}
|
|
update();
|
|
}
|
|
else if(trimPic){
|
|
|
|
int diffX = (widthPoint > qAbs(shiftX))?qAbs(shiftX):widthPoint;
|
|
int diffY = (heightPoint > qAbs(shiftY))?qAbs(shiftY):heightPoint;
|
|
if(shiftX > 0){
|
|
currPositionMove(- diffX,0,true,false,false);
|
|
}
|
|
if(shiftY > 0){
|
|
currPositionMove(0,-diffY,true,false,false);
|
|
}
|
|
heightPoint -= diffY;
|
|
widthPoint -= diffX;
|
|
resize(widthPoint*scale,heightPoint*scale);
|
|
update();
|
|
}
|
|
else if(expandPic){
|
|
int diffX = ((MAX_PIC_WIDGET_WIDTH - widthPoint) > qAbs(shiftX))?qAbs(shiftX):(MAX_PIC_WIDGET_WIDTH - widthPoint);
|
|
int diffY = ((MAX_PIC_WIDGET_HEIGHT - heightPoint) > qAbs(shiftY))?qAbs(shiftY):(MAX_PIC_WIDGET_HEIGHT - heightPoint);
|
|
for(int y = 0; y < heightPoint + diffY;y ++){
|
|
for(int x = 0; x < widthPoint + diffX; x++){
|
|
if(y < heightPoint && x < widthPoint){
|
|
|
|
}
|
|
else {
|
|
//pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = trueColorEnable?backGround.rgba():0xffffffff;
|
|
pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = 0x0000000;
|
|
}
|
|
}
|
|
}
|
|
heightPoint += diffY;
|
|
widthPoint += diffX;
|
|
resize(widthPoint*scale,heightPoint*scale);
|
|
if(shiftX < 0){
|
|
currPositionMove(diffX,0,true,false,false);
|
|
}
|
|
if(shiftY < 0){
|
|
currPositionMove(0,diffY,true,false,false);
|
|
}
|
|
//qDebug() << "diffX:" << diffX << "diffY:" << diffY << "heightPoint:" << heightPoint << "widthPoint" << widthPoint;
|
|
update();
|
|
}
|
|
else {
|
|
int oriX = currXpos;
|
|
int oriY = currYpos;
|
|
currXpos += shiftX;
|
|
currYpos += shiftY;
|
|
currXpos = (currXpos >= 0)?(currXpos%widthPoint):(currXpos + widthPoint);
|
|
currYpos = (currYpos >= 0)?(currYpos%heightPoint):(currYpos + heightPoint);
|
|
update(oriX*scale,oriY*scale,scale,scale);
|
|
update(currXpos*scale,currYpos*scale,scale,scale);
|
|
}
|
|
emit picWidgetModify(widthPoint,heightPoint);
|
|
}
|
|
}
|
|
void zkWidget::ensureCurrPos(){
|
|
if(heightPoint && widthPoint){
|
|
int x = currXpos;
|
|
int y = currYpos;
|
|
|
|
for(int i=0;i<widthPoint;i++){
|
|
for(int j=0;j<heightPoint;j++){
|
|
pointMap[i*MAX_PIC_WIDGET_HEIGHT + j] = pointMap[i*MAX_PIC_WIDGET_HEIGHT + j]?0:1;
|
|
}
|
|
}
|
|
update();
|
|
|
|
//pointMap[x*MAX_PIC_WIDGET_HEIGHT + y] = pointMap[x*MAX_PIC_WIDGET_HEIGHT + y]?0:1;
|
|
//update(x*scale,y*scale,scale,scale);
|
|
modified = true;
|
|
emit picWidgetModify(widthPoint,heightPoint);
|
|
}
|
|
}
|
|
|
|
bool zkWidget::isModified(){
|
|
return modified;
|
|
}
|
|
|
|
void zkWidget::setModified(bool m){
|
|
modified = m;
|
|
}
|
|
|
|
int zkWidget::getHeight(){
|
|
return heightPoint;
|
|
}
|
|
|
|
int zkWidget::getWidth(){
|
|
return widthPoint;
|
|
|
|
}
|
|
|
|
int zkWidget::getScaleValue(){
|
|
return scale;
|
|
}
|
|
|
|
void zkWidget::initWidget(int w,int h){
|
|
scale = 30;
|
|
if(parentWidget()){
|
|
QWidget *widget = parentWidget();
|
|
int width = widget->geometry().width();
|
|
int height = widget->geometry().height();
|
|
int scaleX = w?width/w:width; //不要除零
|
|
int scaleY = h?height/h:height;
|
|
scaleX = scaleX > 0?scaleX:1; //scale不能小于零
|
|
scaleY = scaleY > 0?scaleY:1;
|
|
scale = scaleX > scaleY?scaleY:scaleX;
|
|
}
|
|
currXpos = 0;
|
|
currYpos = 0;
|
|
memset(pointMap,0,sizeof(pointMap));
|
|
resizeWidget(w,h);
|
|
modified = false;
|
|
}
|
|
|
|
|
|
void zkWidget::resizeWidget(int w,int h){
|
|
if(w > MAX_PIC_WIDGET_WIDTH || h > MAX_PIC_WIDGET_HEIGHT){
|
|
QMessageBox::warning(0,tr("警告"),tr("最大支持宽度:%1 高度:%2 当前请求:%3 x %4").arg(MAX_PIC_WIDGET_WIDTH).arg(MAX_PIC_WIDGET_HEIGHT).arg(w).arg(h));
|
|
widthPoint = (w > MAX_PIC_WIDGET_WIDTH)?MAX_PIC_WIDGET_WIDTH:w;
|
|
heightPoint = (h > MAX_PIC_WIDGET_HEIGHT)?MAX_PIC_WIDGET_HEIGHT:h;
|
|
}
|
|
else{
|
|
widthPoint = w;
|
|
heightPoint = h;
|
|
}
|
|
resize(w*scale,h*scale);
|
|
update();
|
|
}
|
|
|
|
|
|
void zkWidget::enlargeDisplay(){
|
|
if(scale < (1<<10)){
|
|
scale = scale + ((scale>2)?scale/2:1);
|
|
resize(widthPoint*scale,heightPoint*scale);
|
|
update();
|
|
}
|
|
}
|
|
|
|
|
|
void zkWidget::reduceDisplay(){
|
|
if(scale > 1){
|
|
scale = scale - ((scale > 2)?scale/3:1);
|
|
resize(widthPoint*scale,heightPoint*scale);
|
|
update();
|
|
}
|
|
}
|
|
|
|
void zkWidget::setScale(int scale){
|
|
if(scale > 1)
|
|
this->scale = scale;
|
|
else
|
|
scale = 1;
|
|
resize(widthPoint*scale,heightPoint*scale);
|
|
update();
|
|
}
|
|
|
|
void zkWidget::loadImage(QString filename,bool forceSize,QString charStr,QFont *font){
|
|
if((widthPoint == 0 || heightPoint == 0) && forceSize){
|
|
QMessageBox::warning(0,"警告","请新创建建图片");
|
|
}
|
|
else {
|
|
bool forceForegroundBackgroundColorFill = false;
|
|
QImage img;
|
|
QFile file(filename);
|
|
if(!filename.isEmpty() && file.exists())
|
|
img.load(filename);
|
|
else if(charStr.size()){
|
|
if(font){
|
|
QFontMetrics fontMetrics(*font);
|
|
//int rightBearing = fontMetrics.rightBearing(QChar(unicode));
|
|
//int leftBearing = fontMetrics.leftBearing(QChar(unicode));
|
|
int width = forceSize?widthPoint:(fontMetrics.width(charStr)) ;
|
|
int height = forceSize?heightPoint:(fontMetrics.ascent() + fontMetrics.descent());
|
|
if(width == 0){
|
|
QMessageBox::warning(0,"警告",QString("字串:%1 在字体%2中不存在").arg(charStr).arg(font->family()));
|
|
return ;
|
|
}
|
|
QSize size(width,height);
|
|
QImage image(size,QImage::Format_ARGB32);
|
|
img = image;
|
|
img.fill(0xffffffff);
|
|
QPainter painter(&img);
|
|
painter.setFont(*font);
|
|
painter.drawText(QPoint(0,fontMetrics.ascent()),charStr);
|
|
forceForegroundBackgroundColorFill = true;
|
|
}
|
|
}
|
|
if(img.isNull()){
|
|
QMessageBox::warning(0,"Warning",QString("File:%1 open failed").arg(filename));
|
|
}
|
|
else {
|
|
int w = img.rect().width();
|
|
int h = img.rect().height();
|
|
memset(pointMap,0,sizeof(pointMap));
|
|
if(!forceSize){
|
|
widthPoint = (w > MAX_PIC_WIDGET_WIDTH)?MAX_PIC_WIDGET_WIDTH:w;
|
|
heightPoint = (h > MAX_PIC_WIDGET_HEIGHT)?MAX_PIC_WIDGET_HEIGHT:h;
|
|
resize(widthPoint*scale,heightPoint*scale);
|
|
}
|
|
QRgb argb = 0;
|
|
for(int i = 0; i < widthPoint;i++){
|
|
for(int j = 0; j < heightPoint ; j++){
|
|
bool pixelVisible = false;
|
|
int init_x = i*w/widthPoint;
|
|
int end_x = (w >= widthPoint)?(i + 1)*w/widthPoint:init_x + 1;
|
|
int init_y = j*h/heightPoint;
|
|
int end_y = (h >= heightPoint)?(j + 1)*h/heightPoint:init_y + 1;
|
|
for(int l = init_x; l < end_x; l++){
|
|
for(int m = init_y; m < end_y; m ++){
|
|
argb = img.pixel(l,m);
|
|
//qDebug() << "i:" << i << "j" << j << " " << QString::number(argb,16);
|
|
if(argb == 0xffffffff) //节约时钟周期
|
|
continue;
|
|
if((argb & 0xff000000) && (((argb&0xff0000) < 0x800000)
|
|
|| ((argb&0xff00) < 0x8000) || ((argb&0xff) < 0x80))){
|
|
pixelVisible = true;
|
|
break;
|
|
}
|
|
}
|
|
if(pixelVisible)
|
|
break;
|
|
}
|
|
if(pixelVisible)
|
|
pointMap[i*MAX_PIC_WIDGET_HEIGHT + j] = 1;
|
|
}
|
|
}
|
|
update();
|
|
setModified(false);
|
|
}
|
|
}
|
|
}
|
|
void zkWidget::saveImage(QString filename){
|
|
if(widthPoint == 0 || heightPoint == 0){
|
|
QMessageBox::warning(0,tr("警告"),tr("请新创建建图片"));
|
|
}
|
|
else {
|
|
QSize size(widthPoint,heightPoint);
|
|
QImage image(size,QImage::Format_ARGB32);
|
|
image.fill(qRgba(0,0,0,0xff));
|
|
for(int i = 0 ; i < widthPoint; i++){
|
|
for(int j = 0; j < heightPoint; j++){
|
|
image.setPixel(i,j,pointMap[i*MAX_PIC_WIDGET_HEIGHT + j]?0xff000000:0xffffffff);
|
|
}
|
|
}
|
|
filename = DOC_ROOT_DIR+ QFileInfo(filename).baseName()+".jpg";
|
|
image.save( filename );
|
|
}
|
|
setModified(false);
|
|
}
|