summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeilin <peilin@multicorewareinc.com>2014-01-02 16:43:25 +0800
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-01-29 08:09:31 +0100
commit7fab8057672737a902ca111eade58046e129f491 (patch)
treec2e35ede66376beff5ed2b1c66f9507b1326fa79
parent0004371c685fdbb04dd2953a4e54dd8b9d065a32 (diff)
add GL text rendering
Change-Id: Ic015559a259fb31455f6c7cd9063716b9241f88a
-rw-r--r--chart2/source/view/main/DummyXShape.cxx4
-rwxr-xr-xchart2/source/view/main/OpenGLRender.cxx269
-rwxr-xr-xchart2/source/view/main/OpenGLRender.hxx24
3 files changed, 294 insertions, 3 deletions
diff --git a/chart2/source/view/main/DummyXShape.cxx b/chart2/source/view/main/DummyXShape.cxx
index 4af48ac91773..9f90031a3cd3 100644
--- a/chart2/source/view/main/DummyXShape.cxx
+++ b/chart2/source/view/main/DummyXShape.cxx
@@ -1054,8 +1054,8 @@ void DummyChart::setSize( const awt::Size& aSize )
// DummyXShape::setSize(aSize);
// mpWindow->SetSizePixel(Size(aSize.Width, aSize.Height));
// pWindow->SetSizePixel(Size(aSize.Width, aSize.Height));
- int width = aSize.Width / 10;
- int height = aSize.Height / 10;
+ int width = aSize.Width / OPENGL_SCALE_VALUE;
+ int height = aSize.Height / OPENGL_SCALE_VALUE;
width = (width + 3) & ~3;
height = (height + 3) & ~3;
mpWindow->SetSizePixel(Size(width, height));
diff --git a/chart2/source/view/main/OpenGLRender.cxx b/chart2/source/view/main/OpenGLRender.cxx
index 3872d3c1eb57..7b4fb1ef99f4 100755
--- a/chart2/source/view/main/OpenGLRender.cxx
+++ b/chart2/source/view/main/OpenGLRender.cxx
@@ -14,11 +14,11 @@
#include <vcl/bitmapex.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/graph.hxx>
-#include <vcl/pngwrite.hxx>
#include <com/sun/star/awt/XBitmap.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <comphelper/InlineContainer.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/CircleKind.hpp>
#include <com/sun/star/drawing/DoubleSequence.hpp>
#include <com/sun/star/drawing/FlagSequence.hpp>
@@ -36,6 +36,9 @@
#include <com/sun/star/uno/Any.hxx>
#include <editeng/unoprnms.hxx>
#include <boost/scoped_array.hpp>
+#include <vcl/virdev.hxx>
+#include <vcl/dibtools.hxx>
+#include <vcl/bmpacc.hxx>
using namespace com::sun::star;
@@ -52,6 +55,8 @@ using namespace std;
#if defined( _WIN32 )
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
#define WGL_SAMPLES_ARB 0x2042
+#else
+typedef unsigned char BYTE;
#endif
const char *ColorFragmemtShader = OPENGL_SHADER (
@@ -1313,4 +1318,266 @@ int OpenGLRender::RenderRectangleShape()
}
+int OpenGLRender::ProcessText(uno::Reference< drawing::XShape > &xShape)
+{
+ uno::Reference< beans::XPropertySet > xProp( xShape, uno::UNO_QUERY );
+ awt::Point aPos( xShape->getPosition() );
+ awt::Size aSize( xShape->getSize());
+ //use device to create text bitmap
+#if 0
+ com::sun::star::uno::Sequence<com::sun::star::beans::Property> Sequenceproperty = xProp->getPropertySetInfo()->getProperties();
+ com::sun::star::beans::Property* Propertyarr = Sequenceproperty.getArray();
+ int count = Sequenceproperty.getLength();
+ printf("Property length:%d\n",count);
+ for(int i=0;i<count;i++)
+ {
+ wprintf(L"item %d,name:%s", i,Propertyarr[i].Name.getStr());
+ com::sun::star::uno::Type t = Propertyarr[i].Type;
+ ::rtl::OUString strtypename = t.getTypeName();
+ sal_Unicode * typeName = (sal_Unicode *)strtypename.getStr();
+ wprintf(L",Type:%s ", typeName);
+ com::sun::star::uno::TypeClass typeclass = t.getTypeClass();
+ com::sun::star::uno::Any value = xProp->getPropertyValue(Propertyarr[i].Name);
+ if(strtypename.equals(OUString(L"string")))
+ {
+ ::rtl::OUString * strvalue = (::rtl::OUString *)value.getValue();
+ wprintf(L",Value:%s \n", strvalue->getStr());
+ }
+ else if(strtypename.equals(OUString(L"short")))
+ {
+ short * shortvalue = (short*)value.getValue();
+ printf(",Value:%d \n",*shortvalue);
+ }
+ else if(strtypename.equals(OUString(L"long")))
+ {
+ long * longvalue = (long*)value.getValue();
+ printf(",Value:%d \n",*longvalue);
+ }
+ else if(strtypename.equals(OUString(L"boolean")))
+ {
+ short * bvalue = (short*)value.getValue();
+ if(*bvalue==0)
+ printf(",Value:false \n");
+ else
+ printf(",Value:true \n");
+ }
+ else
+ {
+ printf(",Value:object \n");
+ }
+ }
+ printf("\n");
+#endif
+ //get the string
+ uno::Reference< text::XTextRange > xTextRange( xShape, uno::UNO_QUERY );
+
+ ::rtl::OUString textValue = xTextRange->getString();
+ wprintf(L"Text value:%s \n", textValue.getStr());
+ //get text color, the output value always be white, so we use black color to text
+ uno::Any co = xProp->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR);
+ long *colorvalue = (long*)co.getValue();
+
+ //get font
+ uno::Any font = xProp->getPropertyValue(UNO_NAME_EDIT_CHAR_FONTNAME);
+ ::rtl::OUString *fontValue = (::rtl::OUString *)font.getValue();
+ wprintf(L"Text font:%s \n", fontValue->getStr());
+ uno::Any rotation = xProp->getPropertyValue(UNO_NAME_MISC_OBJ_ROTATEANGLE);
+ long *rot = (long*)rotation.getValue();
+ cout << "*rot = " << (*rot) << endl;
+ //using the string and the color to create the text texture
+ cout << "color value = " << *colorvalue << endl;
+ CreateTextTexture(textValue, *colorvalue, *fontValue, aPos, aSize, (*rot));
+ RenderTextShape();
+ m_fZStep += 0.01f;
+ return 0;
+}
+
+int OpenGLRender::CreateTextTexture(::rtl::OUString textValue, long color, ::rtl::OUString font, awt::Point aPos, awt::Size aSize, long rotation)
+{
+ VirtualDevice aDevice;
+ Font aFont(font, Size(0, 100));
+ aFont.SetWeight(WEIGHT_BOLD);
+ aFont.SetItalic(ITALIC_NORMAL);
+ aDevice.SetFont(aFont);
+ Rectangle aRect;
+ aDevice.GetTextBoundRect(aRect, textValue);
+ int screenWidth = (aRect.BottomRight().X() + 3) & ~3;
+ int screenHeight = (aRect.BottomRight().Y() + 3) & ~3;
+ aDevice.SetOutputSizePixel(Size(screenWidth * 3, screenHeight));
+ aDevice.DrawText(Point(0, 0), textValue);
+ int bmpWidth = (aRect.Right() - aRect.Left() + 3) & ~3;
+ int bmpHeight = (aRect.Bottom() - aRect.Top() + 3) & ~3;
+ BitmapEx aBitmapEx(aDevice.GetBitmap(aRect.TopLeft(), Size(bmpWidth, bmpHeight)));
+ Bitmap aBitmap( aBitmapEx.GetBitmap());
+ int bitmapsize = aBitmap.GetSizeBytes();
+ BYTE *bitmapBuf = (BYTE *)malloc(bitmapsize * 4 / 3 + BMP_HEADER_LEN);
+ CreateBMPHeaderRGBA(bitmapBuf, bmpWidth, bmpHeight);
+ BitmapReadAccess* pRAcc = aBitmap.AcquireReadAccess();
+ BYTE r = (color & 0x00FF0000) >> 16;
+ BYTE g = (color & 0x0000FF00) >> 8;
+ BYTE b = (color & 0x000000FF);
+
+ cout << "r = " << r << ", g = " << g << ", b = " << b <<endl;
+ for (long ny = 0; ny < bmpHeight; ny++)
+ {
+ for(long nx = 0; nx < bmpWidth; nx++)
+ {
+ sal_uInt8 *pm = pRAcc->GetScanline(ny) + nx * 3;
+ sal_uInt8 *mk = bitmapBuf + BMP_HEADER_LEN + ny * bmpWidth * 4 + nx * 4;
+ if ((*pm == 0xFF) && (*(pm + 1) == 0xFF) && (*(pm + 2) == 0xFF))
+ {
+ *mk = *pm;
+ *(mk + 1) = *(pm + 1);
+ *(mk + 2) = *(pm + 2);
+ *(mk + 3) = 0;
+ }
+ else
+ {
+ *mk = b;
+ *(mk + 1) = g;
+ *(mk + 2) = r;
+ *(mk + 3) = ((0xFF - *pm) + (0xFF - *(pm + 1)) + (0xFF - *(pm + 2))) / 3;
+ }
+ }
+ }
+ aBitmap.ReleaseAccess(pRAcc);
+ m_TextInfo.x = (float)(aPos.X + aSize.Width / 2) / OPENGL_SCALE_VALUE - ((float)m_iWidth / 2);
+ m_TextInfo.y = (float)(aPos.Y + aSize.Height / 2) / OPENGL_SCALE_VALUE - ((float)m_iHeight / 2);
+ m_TextInfo.z = m_fZStep;
+ m_TextInfo.rotation = -(double)rotation * GL_PI / 18000.0f;
+ m_TextInfo.vertex[0] = (float)(-aSize.Width / 2) / OPENGL_SCALE_VALUE;
+ m_TextInfo.vertex[1] = (float)(-aSize.Height / 2) / OPENGL_SCALE_VALUE;
+
+ m_TextInfo.vertex[2] = (float)(aSize.Width / 2) / OPENGL_SCALE_VALUE;
+ m_TextInfo.vertex[3] = (float)(-aSize.Height / 2) / OPENGL_SCALE_VALUE;
+
+ m_TextInfo.vertex[4] = (float)(aSize.Width / 2) / OPENGL_SCALE_VALUE;
+ m_TextInfo.vertex[5] = (float)(aSize.Height / 2) / OPENGL_SCALE_VALUE;
+
+ m_TextInfo.vertex[6] = (float)(-aSize.Width / 2) / OPENGL_SCALE_VALUE;
+ m_TextInfo.vertex[7] = (float)(aSize.Height / 2) / OPENGL_SCALE_VALUE;
+
+ m_fPicLeft = (m_TextInfo.x + m_TextInfo.vertex[0])< m_fPicLeft ? (m_TextInfo.x + m_TextInfo.vertex[0]) : m_fPicLeft;
+
+ m_fPicRight = (m_TextInfo.x + m_TextInfo.vertex[2]) > m_fPicRight ? (m_TextInfo.x + m_TextInfo.vertex[2]) : m_fPicRight;
+
+ m_fPicBottom = (m_TextInfo.y + m_TextInfo.vertex[1]) < m_fPicBottom ? (m_TextInfo.y + m_TextInfo.vertex[1]) : m_fPicBottom;
+
+ m_fPicTop = (m_TextInfo.y + m_TextInfo.vertex[5]) > m_fPicTop ? (m_TextInfo.y + m_TextInfo.vertex[5]) : m_fPicTop;
+ //if has ratotion, we must re caculate the centrol pos
+
+ if (rotation)
+ {
+ //use left top
+ double r = sqrt((double)(aSize.Width * aSize.Width + aSize.Height * aSize.Height)) / 2;
+ double sinOrgAngle = m_TextInfo.vertex[1] / r / 2;
+ double cosOrgAngle = m_TextInfo.vertex[0] / r / 2;
+ double sinDiataAngle = sin(m_TextInfo.rotation);
+ double cosDiataAngle = cos(m_TextInfo.rotation);
+ double x = r * (cosOrgAngle * cosDiataAngle - sinOrgAngle * sinDiataAngle);
+ double y = r * (sinOrgAngle * cosDiataAngle + cosOrgAngle * sinDiataAngle);
+ double diataX = x - m_TextInfo.vertex[0];
+ double diataY = y - m_TextInfo.vertex[1];
+ m_TextInfo.x = m_TextInfo.x - diataX;
+ m_TextInfo.y = m_TextInfo.y - diataY;
+
+ }
+
+ glGenTextures(1, &m_TextInfo.texture);
+ glBindTexture(GL_TEXTURE_2D, m_TextInfo.texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmpWidth, bmpHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, bitmapBuf + BMP_HEADER_LEN);
+ CHECK_GL_ERROR();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ m_TextInfoList.push_back(m_TextInfo);
+ free(bitmapBuf);
+ return 0;
+}
+
+int OpenGLRender::RenderTextShape()
+{
+ int listNum = m_TextInfoList.size();
+ for (int i = 0; i < listNum; i++)
+ {
+ TextInfo &textInfo = m_TextInfoList.front();
+ PosVecf3 trans = {textInfo.x, textInfo.y, textInfo.z};
+ PosVecf3 angle = {0.0f, 0.0f, textInfo.rotation};
+ PosVecf3 scale = {1.0, 1.0, 1.0f};
+ MoveModelf(trans, angle, scale);
+ m_MVP = m_Projection * m_View * m_Model;
+ glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(textInfo.vertex), textInfo.vertex, GL_STATIC_DRAW);
+ glUseProgram(m_TextProID);
+
+ glUniformMatrix4fv(m_TextMatrixID, 1, GL_FALSE, &m_MVP[0][0]);
+ // 1rst attribute buffer : vertices
+ glEnableVertexAttribArray(m_TextVertexID);
+ glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+ glVertexAttribPointer(
+ m_TextVertexID, // attribute. No particular reason for 0, but must match the layout in the shader.
+ 2, // size
+ GL_FLOAT, // type
+ GL_FALSE, // normalized?
+ 0, // stride
+ (void*)0 // array buffer offset
+ );
+ //tex coord
+ glEnableVertexAttribArray(m_TextTexCoordID);
+ glBindBuffer(GL_ARRAY_BUFFER, m_TextTexCoordBuf);
+ glVertexAttribPointer(
+ m_TextTexCoordID, // attribute. No particular reason for 0, but must match the layout in the shader.
+ 2, // size
+ GL_FLOAT, // type
+ GL_FALSE, // normalized?
+ 0, // stride
+ (void*)0 // array buffer offset
+ );
+ //texture
+ glBindTexture(GL_TEXTURE_2D, textInfo.texture);
+ glUniform1i(m_TextTexID, 0);
+ glDrawArrays(GL_QUADS, 0, 4);
+ glDisableVertexAttribArray(m_TextTexCoordID);
+ glDisableVertexAttribArray(m_TextVertexID);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glUseProgram(0);
+ glDeleteTextures(1, &textInfo.texture);
+ m_TextInfoList.pop_front();
+ }
+ return 0;
+}
+
+int OpenGLRender::CreateBMPHeaderRGBA(sal_uInt8 *bmpHeader, int xsize, int ysize)
+{
+ unsigned char header[BMP_HEADER_LEN] = {
+ 0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
+ 54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+ };
+
+ long file_size = (long)xsize * (long)ysize * 4 + 54;
+ header[2] = (unsigned char)(file_size &0x000000ff);
+ header[3] = (file_size >> 8) & 0x000000ff;
+ header[4] = (file_size >> 16) & 0x000000ff;
+ header[5] = (file_size >> 24) & 0x000000ff;
+
+ long width = xsize;
+ header[18] = width & 0x000000ff;
+ header[19] = (width >> 8) &0x000000ff;
+ header[20] = (width >> 16) &0x000000ff;
+ header[21] = (width >> 24) &0x000000ff;
+
+ long height = -ysize;
+ header[22] = height &0x000000ff;
+ header[23] = (height >> 8) &0x000000ff;
+ header[24] = (height >> 16) &0x000000ff;
+ header[25] = (height >> 24) &0x000000ff;
+ memcpy(bmpHeader, header, BMP_HEADER_LEN);
+ return 0;
+
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/view/main/OpenGLRender.hxx b/chart2/source/view/main/OpenGLRender.hxx
index f0fcb4a6b347..5848c123d91b 100755
--- a/chart2/source/view/main/OpenGLRender.hxx
+++ b/chart2/source/view/main/OpenGLRender.hxx
@@ -55,6 +55,8 @@ namespace unx
#define OPENGL_SCALE_VALUE 20
using namespace std;
+using namespace ::com::sun::star;
+using ::com::sun::star::uno::Reference;
typedef struct PosVeci3
{
@@ -97,6 +99,15 @@ typedef struct RectanglePointList
float xScale;
float yScale;
}RectanglePointList;
+typedef struct TextInfo
+{
+ GLuint texture;
+ float x;
+ float y;
+ float z;
+ double rotation;
+ float vertex[8];
+}TextInfo;
/// Holds the information of our new child window
struct GLWindow
@@ -142,6 +153,7 @@ public:
int GetHeight();
void Release();
int CreateBMPHeader(sal_uInt8 *bmpHeader, int xsize, int ysize);
+ int CreateBMPHeaderRGBA(sal_uInt8 *bmpHeader, int xsize, int ysize);
int RenderLine2FBO(int wholeFlag);
int SetLine2DShapePoint(float x, float y, int listLength);
void SetLine2DColor(sal_uInt8 r, sal_uInt8 g, sal_uInt8 b);
@@ -164,6 +176,9 @@ public:
int RenderRectangleShape();
int RectangleShapePoint(float x, float y, float directionX, float directionY);
+ int ProcessText(com::sun::star::uno::Reference<com::sun::star::drawing::XShape > &xShape);
+ int CreateTextTexture(::rtl::OUString textValue, long color, ::rtl::OUString font, awt::Point aPos, awt::Size aSize, long rotation);
+ int RenderTextShape();
private:
GLint LoadShaders(const char *vertexShader,const char *fragmentShader);
int CreateTextureObj(int width, int height);
@@ -292,6 +307,15 @@ private:
RectanglePointList m_RectangleList;
list <RectanglePointList> m_RectangleShapePointList;
+ // add for text
+ TextInfo m_TextInfo;
+ list <TextInfo> m_TextInfoList;
+ GLint m_TextProID;
+ GLint m_TextMatrixID;
+ GLint m_TextVertexID;
+ GLint m_TextTexCoordID;
+ GLuint m_TextTexCoordBuf;
+ GLint m_TextTexID;
};