void RectRenderComponent::OnRender(VariantList *pVList) { if (*m_pAlpha > 0.01) { CL_Vec2f vFinalPos = pVList->m_variant[0].GetVector2()+*m_pPos2d; uint32 color = ColorCombine(*m_pColor, *m_pColorMod, *m_pAlpha); if (GET_ALPHA(color) == 0) return; CL_Vec2f vRotationPt = vFinalPos; g_globalBatcher.Flush(); if (*m_pRotation != 0) { SetupOrtho(); PushRotationMatrix(*m_pRotation, vRotationPt); vFinalPos -= vRotationPt; } CL_Rectf r = CL_Rectf(vFinalPos.x, vFinalPos.y, vFinalPos.x+ m_pSize2d->x, vFinalPos.y+m_pSize2d->y); if (*m_pVisualStyle != STYLE_BORDER_ONLY) { DrawFilledRect(r, color); } if (GET_ALPHA(*m_pBorderColor) > 0) { DrawRect(r, *m_pBorderColor, 1); } if (*m_pVisualStyle == STYLE_3D) { int shadedColor = ColorCombineMix(color, MAKE_RGBA(0,0,0,255), 0.4f); DrawLine(shadedColor, vFinalPos.x, vFinalPos.y+m_pSize2d->y, vFinalPos.x+m_pSize2d->x,vFinalPos.y+m_pSize2d->y, 1); DrawLine(shadedColor, vFinalPos.x+m_pSize2d->x, vFinalPos.y, vFinalPos.x+m_pSize2d->x,vFinalPos.y+m_pSize2d->y, 1); shadedColor = ColorCombineMix(color, MAKE_RGBA(255,255,255 ,255), 0.4f); DrawLine(shadedColor, vFinalPos.x, vFinalPos.y, vFinalPos.x,vFinalPos.y+m_pSize2d->y, 1); DrawLine(shadedColor, vFinalPos.x, vFinalPos.y, vFinalPos.x+m_pSize2d->x,vFinalPos.y, 1); } if (*m_pRotation != 0) { PopRotationMatrix(); } } }
void OverlayRenderComponent::OnRender(VariantList *pVList) { if (*m_pVisible == 0) return; if (m_pTex && m_pTex->IsLoaded() && *m_pAlpha > 0.01) { CL_Vec2f vFinalPos = pVList->m_variant[0].GetVector2()+*m_pPos2d; unsigned int finalColor = ColorCombine(*m_pColor, *m_pColorMod, *m_pAlpha); if (GET_ALPHA(finalColor) == 0) return; if (vFinalPos.y < -m_pSize2d->y && *m_pRotation == 0) return; //if rotation is enabled, we don't do this early exit check as it could be incorrect if (vFinalPos.y > GetOrthoRenderSizeYf() && *m_pRotation == 0) return; //if rotation is enabled, we don't do this early exit check as it could be incorrect CL_Vec2f vRotationPt = vFinalPos; vRotationPt.x += (m_pTex->GetFrameSize().x* (m_pScale2d->x)) * m_pRotationCenter->x; vRotationPt.y += (m_pTex->GetFrameSize().y* (m_pScale2d->y)) * m_pRotationCenter->y; if (m_pScale2d->x != 1 || m_pScale2d->y != 1 || *m_pFlipX != 0 || *m_pFlipY != 0) { if (m_pScale2d->x != 0 && m_pScale2d->y != 0) { m_pTex->BlitScaledAnim(vFinalPos.x, vFinalPos.y, *m_pFrameX, *m_pFrameY,*m_pScale2d, ALIGNMENT_UPPER_LEFT, finalColor, *m_pRotation, vRotationPt, *m_pFlipX != 0, *m_pFlipY != 0); } } else { m_pTex->BlitAnim(vFinalPos.x, vFinalPos.y, *m_pFrameX, *m_pFrameY, finalColor, *m_pRotation, vRotationPt); } } }
void DrawEllipse (const int segments, CL_Vec2f vPos, float radianWidth, float radiusHeight, bool vFilled, uint32 color) { SetupOrtho(); glPushMatrix(); glTranslatef(vPos.x, vPos.y, 0.0); vector<float> vertices; vertices.resize(segments*2); glEnable (GL_LINE_SMOOTH); int count=0; for (GLfloat i = 0; i < 360.0f; i+=(360.0f/segments)) { vertices[count++] = (float(cos(DEG2RAD(i)))*radianWidth); vertices[count++] = (float(sin(DEG2RAD(i)))*radiusHeight); } glColor4x( (color >>8 & 0xFF)*256, (color>>16& 0xFF)*256, (color>>24& 0xFF)*256, (color&0xFF)*256); if (GET_ALPHA(color) != 255) { glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); glVertexPointer (2, GL_FLOAT , 0, &vertices.at(0)); glDrawArrays ((vFilled) ? GL_TRIANGLE_FAN : GL_LINE_LOOP, 0, segments); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); if (GET_ALPHA(color) != 255) { glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); } glColor4x(1 << 16, 1 << 16, 1 << 16, 1 << 16); glPopMatrix(); }
int main(int argc, char* argv[]) { GPU_Target* screen; printRenderers(); screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS); if(screen == NULL) return -1; printCurrentRenderer(); { Uint32 startTime; long frameCount; Uint8 done; SDL_Event event; int mx, my; GPU_Image* image; GPU_Target* target; SDL_Color c; image = GPU_LoadImage("data/test.bmp"); if(image == NULL) return -1; target = GPU_LoadTarget(image); startTime = SDL_GetTicks(); frameCount = 0; done = 0; while(!done) { while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) done = 1; else if(event.type == SDL_KEYDOWN) { if(event.key.keysym.sym == SDLK_ESCAPE) done = 1; } } SDL_GetMouseState(&mx, &my); c = GPU_GetPixel(target, mx - 50, my - 50); GPU_ClearRGBA(screen, c.r, c.g, c.b, GET_ALPHA(c)); GPU_Blit(image, NULL, screen, image->w/2 + 50, image->h/2 + 50); GPU_Flip(screen); frameCount++; if(frameCount%500 == 0) printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); } printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); GPU_FreeImage(image); } GPU_Quit(); return 0; }
void TextBoxRenderComponent::DrawTextNormal(CL_Vec2f vPos) { //go through all text and draw it if (vPos.x > GetScreenSizeX()) return; //no use drawing stuff that is off the screen to the right float lineHeight = GetBaseApp()->GetFont(eFont(*m_pFontID))->GetLineHeight(*m_pFontScale); uint32 color = ColorCombine(*m_pColor, *m_pColorMod, *m_pAlpha); FontStateStack state; for (unsigned int i=0; i < m_lines.size(); i++) { if (vPos.y+lineHeight < 0) { //it's above the screen and doesn't need to be drawn.. but we still want to process it for color information. GetBaseApp()->GetFont(eFont(*m_pFontID))->DrawScaledFakeToUpdateState(m_lines[i], color, &state); vPos.y += lineHeight; continue; //no use drawing stuff that is above the screen } if (vPos.y > GetOrthoRenderSizeYf()) { break; //no use drawing any more down here } float lineSizeX; switch (*m_pTextAlignment) { case ALIGNMENT_UPPER_CENTER: //center the text on its line. No reason why we couldn't cache this size data, but I suspect it's not a big hit compared to the //actual rendering. lineSizeX = GetBaseApp()->GetFont(eFont(*m_pFontID))->MeasureText(m_lines[i], *m_pFontScale).x; if (*m_pShadowColor != 0) { GetBaseApp()->GetFont(eFont(*m_pFontID))->DrawScaledSolidColor( (vPos.x + ( (m_pSize2d->x-lineSizeX)/2))+2, vPos.y+2, m_lines[i], *m_pFontScale,ColorCombine(*m_pShadowColor, MAKE_RGBA(255,255,255,255), (float)GET_ALPHA(color)/255), NULL, &g_globalBatcher); } GetBaseApp()->GetFont(eFont(*m_pFontID))->DrawScaled(vPos.x + ( (m_pSize2d->x-lineSizeX)/2), vPos.y, m_lines[i], *m_pFontScale, color, &state, &g_globalBatcher); break; default: if (*m_pShadowColor != 0) { GetBaseApp()->GetFont(eFont(*m_pFontID))->DrawScaledSolidColor(vPos.x+2, vPos.y+2, m_lines[i], *m_pFontScale, ColorCombine(*m_pShadowColor, MAKE_RGBA(255,255,255,255), (float)GET_ALPHA(color)/255), NULL, &g_globalBatcher); } GetBaseApp()->GetFont(eFont(*m_pFontID))->DrawScaled(vPos.x, vPos.y, m_lines[i], *m_pFontScale, color, &state, &g_globalBatcher); break; } //advance to the next line vPos.y += lineHeight; } }
int main(int argc, char* argv[]) { GPU_Target* screen; printRenderers(); screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS); if(screen == NULL) return -1; printCurrentRenderer(); { Uint32 startTime; long frameCount; Uint8 done; SDL_Event event; int shapeType; int numShapeTypes; int i; #define NUM_COLORS 20 SDL_Color colors[NUM_COLORS]; #define NUM_PIXELS NUM_COLORS int px[NUM_PIXELS]; int py[NUM_PIXELS]; #define NUM_LINES NUM_COLORS int lx1[NUM_LINES]; int ly1[NUM_LINES]; int lx2[NUM_LINES]; int ly2[NUM_LINES]; #define NUM_TRIS NUM_COLORS int tx1[NUM_TRIS]; int ty1[NUM_TRIS]; int tx2[NUM_TRIS]; int ty2[NUM_TRIS]; int tx3[NUM_TRIS]; int ty3[NUM_TRIS]; #define NUM_RECTS NUM_COLORS int rx1[NUM_RECTS]; int ry1[NUM_RECTS]; int rx2[NUM_RECTS]; int ry2[NUM_RECTS]; float rr[NUM_RECTS]; #define NUM_ARCS NUM_COLORS int ax[NUM_ARCS]; int ay[NUM_ARCS]; float ar[NUM_ARCS]; float ar2[NUM_ARCS]; float aa1[NUM_ARCS]; float aa2[NUM_ARCS]; #define NUM_POLYS NUM_COLORS int pn[NUM_POLYS]; float* pv[NUM_POLYS]; Uint8 blend; float thickness; startTime = SDL_GetTicks(); frameCount = 0; shapeType = 0; numShapeTypes = 18; for(i = 0; i < NUM_COLORS; i++) { colors[i].r = rand()%256; colors[i].g = rand()%256; colors[i].b = rand()%256; GET_ALPHA(colors[i]) = rand()%256; } for(i = 0; i < NUM_PIXELS; i++) { px[i] = rand()%screen->w; py[i] = rand()%screen->h; } for(i = 0; i < NUM_LINES; i++) { lx1[i] = rand()%screen->w; ly1[i] = rand()%screen->h; lx2[i] = rand()%screen->w; ly2[i] = rand()%screen->h; } for(i = 0; i < NUM_TRIS; i++) { tx1[i] = rand()%screen->w; ty1[i] = rand()%screen->h; tx2[i] = rand()%screen->w; ty2[i] = rand()%screen->h; tx3[i] = rand()%screen->w; ty3[i] = rand()%screen->h; } for(i = 0; i < NUM_RECTS; i++) { rx1[i] = rand()%screen->w; ry1[i] = rand()%screen->h; rx2[i] = rand()%screen->w; ry2[i] = rand()%screen->h; rr[i] = rand()%10 + 2; } for(i = 0; i < NUM_ARCS; i++) { ax[i] = rand()%screen->w; ay[i] = rand()%screen->h; ar[i] = (rand()%screen->h)/10.0f; ar2[i] = ((rand()%101)/100.0f)*ar[i]; aa1[i] = rand()%360; aa2[i] = rand()%360; } for(i = 0; i < NUM_POLYS; i++) { float cx = rand()%screen->w; float cy = rand()%screen->h; float radius = 20 + rand()%(screen->w/8); int j; pn[i] = rand()%8 + 3; pv[i] = (float*)malloc(2*pn[i]*sizeof(float)); for(j = 0; j < pn[i]*2; j+=2) { pv[i][j] = cx + radius*cos(2*M_PI*(((float)j)/(pn[i]*2))) + rand()%((int)radius/2); pv[i][j+1] = cy + radius*sin(2*M_PI*(((float)j)/(pn[i]*2))) + rand()%((int)radius/2); } } blend = 0; thickness = 1.0f; GPU_SetShapeBlending(blend); done = 0; while(!done) { while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) done = 1; else if(event.type == SDL_KEYDOWN) { if(event.key.keysym.sym == SDLK_ESCAPE) done = 1; else if(event.key.keysym.sym == SDLK_SPACE) { shapeType++; if(shapeType >= numShapeTypes) shapeType = 0; } else if(event.key.keysym.sym == SDLK_BACKSPACE) { shapeType--; if(shapeType < 0) shapeType = numShapeTypes-1; } else if(event.key.keysym.sym == SDLK_b) { blend = !blend; GPU_SetShapeBlending(blend); } else if(event.key.keysym.sym == SDLK_UP || event.key.keysym.sym == SDLK_EQUALS) { thickness += 0.25f; GPU_LogError("thickness: %.2f\n", thickness); GPU_SetLineThickness(thickness); } else if(event.key.keysym.sym == SDLK_DOWN || event.key.keysym.sym == SDLK_MINUS) { if(thickness > 0.25f) thickness -= 0.25f; GPU_LogError("thickness: %.2f\n", thickness); GPU_SetLineThickness(thickness); } } else if(event.type == SDL_MOUSEBUTTONDOWN) { if(event.button.button == SDL_BUTTON_LEFT) { shapeType++; if(shapeType >= numShapeTypes) shapeType = 0; } else if(event.button.button == SDL_BUTTON_RIGHT) { shapeType--; if(shapeType < 0) shapeType = numShapeTypes-1; } } } GPU_Clear(screen); switch(shapeType) { case 0: for(i = 0; i < NUM_PIXELS; i++) { GPU_Pixel(screen, px[i], py[i], colors[i]); } break; case 1: for(i = 0; i < NUM_LINES; i++) { GPU_Line(screen, lx1[i], ly1[i], lx2[i], ly2[i], colors[i]); } break; case 2: for(i = 0; i < NUM_TRIS; i++) { GPU_Tri(screen, tx1[i], ty1[i], tx2[i], ty2[i], tx3[i], ty3[i], colors[i]); } break; case 3: for(i = 0; i < NUM_TRIS; i++) { GPU_TriFilled(screen, tx1[i], ty1[i], tx2[i], ty2[i], tx3[i], ty3[i], colors[i]); } break; case 4: for(i = 0; i < NUM_RECTS; i++) { GPU_Rectangle(screen, rx1[i], ry1[i], rx2[i], ry2[i], colors[i]); } break; case 5: for(i = 0; i < NUM_RECTS; i++) { GPU_RectangleFilled(screen, rx1[i], ry1[i], rx2[i], ry2[i], colors[i]); } break; case 6: for(i = 0; i < NUM_RECTS; i++) { GPU_RectangleRound(screen, rx1[i], ry1[i], rx2[i], ry2[i], rr[i], colors[i]); } break; case 7: for(i = 0; i < NUM_RECTS; i++) { GPU_RectangleRoundFilled(screen, rx1[i], ry1[i], rx2[i], ry2[i], rr[i], colors[i]); } break; case 8: for(i = 0; i < NUM_ARCS; i++) { GPU_Arc(screen, ax[i], ay[i], ar[i], aa1[i], aa2[i], colors[i]); } break; case 9: for(i = 0; i < NUM_ARCS; i++) { GPU_ArcFilled(screen, ax[i], ay[i], ar[i], aa1[i], aa2[i], colors[i]); } break; case 10: for(i = 0; i < NUM_ARCS; i++) { GPU_Circle(screen, ax[i], ay[i], ar[i], colors[i]); } break; case 11: for(i = 0; i < NUM_ARCS; i++) { GPU_CircleFilled(screen, ax[i], ay[i], ar[i], colors[i]); } break; case 12: for(i = 0; i < NUM_ARCS; i++) { GPU_Ellipse(screen, ax[i], ay[i], ar[i], ar2[i], aa1[i], colors[i]); } break; case 13: for(i = 0; i < NUM_ARCS; i++) { GPU_EllipseFilled(screen, ax[i], ay[i], ar[i], ar2[i], aa1[i], colors[i]); } break; case 14: for(i = 0; i < NUM_ARCS; i++) { GPU_Sector(screen, ax[i], ay[i], ar[i], ar2[i], aa1[i], aa2[i], colors[i]); } break; case 15: for(i = 0; i < NUM_ARCS; i++) { GPU_SectorFilled(screen, ax[i], ay[i], ar[i], ar2[i], aa1[i], aa2[i], colors[i]); } break; case 16: for(i = 0; i < NUM_POLYS; i++) { GPU_Polygon(screen, pn[i], pv[i], colors[i]); } break; case 17: for(i = 0; i < NUM_POLYS; i++) { GPU_PolygonFilled(screen, pn[i], pv[i], colors[i]); } break; } GPU_Flip(screen); frameCount++; if(frameCount%500 == 0) printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); } printf("Average FPS: %.2f\n", 1000.0f*frameCount/(SDL_GetTicks() - startTime)); for(i = 0; i < NUM_POLYS; i++) { free(pv[i]); } } GPU_Quit(); return 0; }
/** * CParticleEffect::initParticle * @date Modified June 01, 2006 */ void CParticleEffect::initParticle(CParticleManager::SParticle* pParticle, D3DXMATRIX* mOffset) { D3DXMATRIX mPosOffset, mOrientation = *mOffset; D3DXMatrixIdentity(&mPosOffset); mPosOffset._41 = mOffset->_41; mPosOffset._42 = mOffset->_42; mPosOffset._43 = mOffset->_43; mOrientation._41 = mOrientation._42 = mOrientation._43 = 0.0f; mOrientation._44 = 1.0f; float fMinVel, fMaxVel; D3DXVec3Normalize(&fMinVel, &m_vMinVelocity, &m_vMinVelocity); D3DXVec3Normalize(&fMaxVel, &m_vMaxVelocity, &m_vMaxVelocity); D3DXVec3TransformCoord(&m_vMinVelocityTrans, &m_vMinVelocity, &mOrientation); D3DXVec3TransformCoord(&m_vMaxVelocityTrans, &m_vMaxVelocity, &mOrientation); m_vMinVelocity *= fMinVel; m_vMaxVelocity *= fMaxVel; // Update attributes BYTE cR = GET_RED(pParticle->Color), cG = GET_GREEN(pParticle->Color), cB = GET_BLUE(pParticle->Color), cA = GET_ALPHA(pParticle->Color); for(size_t j = 0; j < m_vAttributes.size(); ++j) { float fScale = m_vAttributes[j]->getValue(0.0f); switch(m_vAttributes[j]->getType()) { case CParticleAttribute::ATR_COLORRED: cR = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_COLORGREEN: cG = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_COLORBLUE: cB = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_COLORALPHA: cA = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_SIZE: pParticle->Size = fScale; break; case CParticleAttribute::ATR_ROTATION: pParticle->Rotation = degreesToRadians(fScale); break; case CParticleAttribute::ATR_ACCELX: pParticle->Acceleration.x = fScale; break; case CParticleAttribute::ATR_ACCELY: pParticle->Acceleration.y = fScale; break; case CParticleAttribute::ATR_ACCELZ: pParticle->Acceleration.z = fScale; break; } } pParticle->Color = D3DCOLOR_ARGB(cA, cR, cG, cB); getRandomVector(&pParticle->Velocity, &m_vMinVelocityTrans, &m_vMaxVelocityTrans); pParticle->Velocity *= getRandomFloat(fMinVel, fMaxVel); m_vMinVelocityTrans *= fMinVel; m_vMaxVelocityTrans *= fMaxVel; D3DXVECTOR3 vMin(0.0f, 0.0f, 0.0f), vMax(0.0f, 0.0f, 0.0f); switch(m_eSpawnShape) { case SH_CUBE: vMin.x = -m_vSpawnRadius.x; vMin.y = -m_vSpawnRadius.y; vMin.z = -m_vSpawnRadius.z; getRandomVector(&pParticle->Position, &vMin, &m_vSpawnRadius); break; case SH_SQUARE: vMin.x = -m_vSpawnRadius.x; vMin.z = -m_vSpawnRadius.z; vMax.x = m_vSpawnRadius.x; vMax.z = m_vSpawnRadius.z; getRandomVector(&pParticle->Position, &vMin, &vMax); break; case SH_SPHERE: getRandomVector(&vMin, -1.0f, 1.0f); D3DXVec3Normalize(&vMin, &vMin); pParticle->Position.x = vMin.x * m_vSpawnRadius.x; pParticle->Position.y = vMin.y * m_vSpawnRadius.x; pParticle->Position.z = vMin.z * m_vSpawnRadius.x; break; case SH_CIRCLE: getRandomVector(&vMin, -1.0f, 1.0f); D3DXVec3Normalize(&vMin, &vMin); pParticle->Position.x = vMin.x * m_vSpawnRadius.x; pParticle->Position.y = 0.0f; pParticle->Position.z = vMin.z * m_vSpawnRadius.x; break; } D3DXVec3TransformCoord(&pParticle->Position, &pParticle->Position, &mPosOffset); }
/** * CParticleEffect::updateParticle * @date Modified Jun 01, 2006 */ bool CParticleEffect::updateParticle(float fTime, CParticleManager::SParticle* pParticle) { CParticleManager::SParticle* p = pParticle; p->LivingTime += fTime; // Check for dead particles if(p->LivingTime >= m_fEffectLength) { return false; } else { D3DXVECTOR3 vVel = p->Velocity * fTime; D3DXVECTOR3 vAccel = p->Acceleration * fTime; D3DXVec3Add(&p->Position, &p->Position, &vVel); D3DXVec3Add(&p->Velocity, &p->Velocity, &vAccel); if(m_bBounce && p->Position.y < 0.0f) { p->Position.y = 0.0f; p->Velocity.x /= m_fInvRestitution; p->Velocity.y = (-p->Velocity.y) / m_fInvRestitution; p->Velocity.z /= m_fInvRestitution; } } // Update attributes BYTE cR = GET_RED(p->Color), cG = GET_GREEN(p->Color), cB = GET_BLUE(p->Color), cA = GET_ALPHA(p->Color); for(size_t j = 0; j < m_vAttributes.size(); ++j) { float fScale = m_vAttributes[j]->getValue(p->LivingTime / m_fEffectLength); switch(m_vAttributes[j]->getType()) { case CParticleAttribute::ATR_COLORRED: cR = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_COLORGREEN: cG = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_COLORBLUE: cB = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_COLORALPHA: cA = (BYTE)(fScale * 255.0f); break; case CParticleAttribute::ATR_SIZE: p->Size = fScale; break; case CParticleAttribute::ATR_ROTATION: p->Rotation = degreesToRadians(fScale); break; case CParticleAttribute::ATR_ACCELX: p->Acceleration.x = fScale; break; case CParticleAttribute::ATR_ACCELY: p->Acceleration.y = fScale; break; case CParticleAttribute::ATR_ACCELZ: p->Acceleration.z = fScale; break; } } p->Color = D3DCOLOR_ARGB(cA, cR, cG, cB); return true; }
string PrintColor(uint32 color) { char st[128]; sprintf(st, "%d, %d, %d, %d", GET_RED(color), GET_GREEN(color), GET_BLUE(color), GET_ALPHA(color)); return string(st); }
KisImportExportFilter::ConversionStatus KisXCFImport::loadFromDevice(QIODevice* device, KisDocument* doc) { dbgFile << "Start decoding file"; // Read the file into memory device->open(QIODevice::ReadOnly); QByteArray data = device->readAll(); xcf_file = (uint8_t*)data.data(); xcf_length = data.size(); device->close(); // Decode the data getBasicXcfInfo() ; initColormap(); dbgFile << XCF.version << "width = " << XCF.width << "height = " << XCF.height << "layers = " << XCF.numLayers; // Create the image KisImageSP image = new KisImage(doc->createUndoStore(), XCF.width, XCF.height, KoColorSpaceRegistry::instance()->rgb8(), "built image"); QVector<Layer> layers; uint maxDepth = 0; // Read layers for (int i = 0; i < XCF.numLayers; ++i) { Layer layer; xcfLayer& xcflayer = XCF.layers[i]; dbgFile << i << " name = " << xcflayer.name << " opacity = " << xcflayer.opacity << "group:" << xcflayer.isGroup << xcflayer.pathLength; dbgFile << ppVar(xcflayer.dim.width) << ppVar(xcflayer.dim.height) << ppVar(xcflayer.dim.tilesx) << ppVar(xcflayer.dim.tilesy) << ppVar(xcflayer.dim.ntiles) << ppVar(xcflayer.dim.c.t) << ppVar(xcflayer.dim.c.l) << ppVar(xcflayer.dim.c.r) << ppVar(xcflayer.dim.c.b); maxDepth = qMax(maxDepth, xcflayer.pathLength); bool isRgbA = false; // Select the color space const KoColorSpace* colorSpace = 0; switch (xcflayer.type) { case GIMP_INDEXED_IMAGE: case GIMP_INDEXEDA_IMAGE: case GIMP_RGB_IMAGE: case GIMP_RGBA_IMAGE: colorSpace = KoColorSpaceRegistry::instance()->rgb8(); isRgbA = true; break; case GIMP_GRAY_IMAGE: case GIMP_GRAYA_IMAGE: colorSpace = KoColorSpaceRegistry::instance()->colorSpace(GrayAColorModelID.id(), Integer8BitsColorDepthID.id(), ""); isRgbA = false; break; } // Create the layer KisLayerSP kisLayer; if (xcflayer.isGroup) { kisLayer = new KisGroupLayer(image, QString::fromUtf8(xcflayer.name), xcflayer.opacity); } else { kisLayer = new KisPaintLayer(image, QString::fromUtf8(xcflayer.name), xcflayer.opacity, colorSpace); } // Set some properties kisLayer->setCompositeOpId(layerModeG2K(xcflayer.mode)); kisLayer->setVisible(xcflayer.isVisible); kisLayer->disableAlphaChannel(xcflayer.mode != GIMP_NORMAL_MODE); layer.layer = kisLayer; layer.depth = xcflayer.pathLength; // Copy the data in the image initLayer(&xcflayer); int left = xcflayer.dim.c.l; int top = xcflayer.dim.c.t; if (!xcflayer.isGroup) { // Copy the data; for (unsigned int x = 0; x < xcflayer.dim.width; x += TILE_WIDTH) { for (unsigned int y = 0; y < xcflayer.dim.height; y += TILE_HEIGHT) { rect want; want.l = x + left; want.t = y + top; want.b = want.t + TILE_HEIGHT; want.r = want.l + TILE_WIDTH; Tile* tile = getMaskOrLayerTile(&xcflayer.dim, &xcflayer.pixels, want); KisHLineIteratorSP it = kisLayer->paintDevice()->createHLineIteratorNG(x, y, TILE_WIDTH); rgba* data = tile->pixels; for (int v = 0; v < TILE_HEIGHT; ++v) { if (isRgbA) { // RGB image do { KoBgrTraits<quint8>::setRed(it->rawData(), GET_RED(*data)); KoBgrTraits<quint8>::setGreen(it->rawData(), GET_GREEN(*data)); KoBgrTraits<quint8>::setBlue(it->rawData(), GET_BLUE(*data)); KoBgrTraits<quint8>::setOpacity(it->rawData(), quint8(GET_ALPHA(*data)), 1); ++data; } while (it->nextPixel()); } else { // Grayscale image do { it->rawData()[0] = GET_RED(*data); it->rawData()[1] = GET_ALPHA(*data); ++data; } while (it->nextPixel()); } it->nextRow(); } } } // Move the layer to its position kisLayer->paintDevice()->setX(left); kisLayer->paintDevice()->setY(top); } // Create the mask if (xcflayer.hasMask) { KisTransparencyMaskSP mask = new KisTransparencyMask(); layer.mask = mask; mask->initSelection(kisLayer); for (unsigned int x = 0; x < xcflayer.dim.width; x += TILE_WIDTH) { for (unsigned int y = 0; y < xcflayer.dim.height; y += TILE_HEIGHT) { rect want; want.l = x + left; want.t = y + top; want.b = want.t + TILE_HEIGHT; want.r = want.l + TILE_WIDTH; Tile* tile = getMaskOrLayerTile(&xcflayer.dim, &xcflayer.mask, want); KisHLineIteratorSP it = mask->paintDevice()->createHLineIteratorNG(x, y, TILE_WIDTH); rgba* data = tile->pixels; for (int v = 0; v < TILE_HEIGHT; ++v) { do { it->rawData()[0] = GET_ALPHA(*data); ++data; } while (it->nextPixel()); it->nextRow(); } } } mask->paintDevice()->setX(left); mask->paintDevice()->setY(top); image->addNode(mask, kisLayer); } dbgFile << xcflayer.pixels.tileptrs; layers.append(layer); } for (int i = 0; i <= maxDepth; ++i) { addLayers(layers, image, i); } doc->setCurrentImage(image); return KisImportExportFilter::OK; }
DEF_FUNC(mlib_ImageDivAlpha_U8, mlib_u8) { mlib_d64 mask7FFF = vis_to_double_dup(0x7FFF7FFF); mlib_d64 *p_tbl; mlib_d64 *buffs, *buffd; mlib_d64 *sp, *dp; mlib_d64 ss, d0, d1, dd, a0, a1; mlib_s32 cmask = (1 << (channel - alpha - 1)); mlib_s32 ww, dflag, i, j; vis_write_gsr(7 << 3); cmask |= (cmask << channel); cmask |= (cmask << 2 * channel); if (channel == 3) { p_tbl = (mlib_d64 *)mlib_DivAlpha_tbl; } else { p_tbl = (mlib_d64 *)mlib_DivAlpha_tbl4 + alpha * 256; } width *= channel; ww = (width + 7) / 8; if (channel == 3) { ww = 3 * ((ww + 2) / 3); } buffs = __mlib_malloc(2 * sizeof (mlib_d64) * ww); if (buffs == NULL) { return (MLIB_FAILURE); } buffd = buffs + ww; for (j = 0; j < height; j++) { mlib_u8 *ap = sl + alpha; if (((int)sl & 7)) { MEM_COPY(sl, buffs, width * sizeof (mlib_u8)); sp = buffs; } else { sp = (mlib_d64 *)sl; } dflag = 0; if (((int)dl | width) & 7) { dp = buffd; dflag = 1; } else { dp = (mlib_d64 *)dl; } if (channel == 4) { #pragma pipeloop(0) for (i = 0; i < ww; i++) { ss = *sp; GET_ALPHA(a0, sp, alpha); GET_ALPHA(a1, sp, alpha + 4); DIV_ALPHA(d0, vis_read_hi(ss), a0); DIV_ALPHA(d1, vis_read_lo(ss), a1); *dp = vis_fpack16_pair(d0, d1); sp++; dp++; } } else if (channel == 3) { mlib_d64 a0, a1, a2, aa; mlib_d64 b0, b1, b2, bb; mlib_d64 s0, s1, s2; mlib_d64 d0, d1; mlib_s32 cmask0, cmask1, cmask2; cmask0 = 0x492 >> alpha; cmask1 = 0x492 >> (alpha + 1); cmask2 = 0x492 >> (alpha + 2); vis_alignaddr((void *)0, 4); if (alpha == 0) { #pragma pipeloop(0) for (i = 0; i < ww - 3; i += 3) { GET_ALPHA_3CH_0(); DIV_ALPHA_3CH(); } if (i < ww) { GET_ALPHA_3CH_0_NF(); DIV_ALPHA_3CH_NF(); } } else if (alpha == 1) { #pragma pipeloop(0) for (i = 0; i < ww - 3; i += 3) { GET_ALPHA_3CH_1(); DIV_ALPHA_3CH(); } if (i < ww) { GET_ALPHA_3CH_1_NF(); DIV_ALPHA_3CH_NF(); } } else { /* if (alpha == 2) */ #pragma pipeloop(0) for (i = 0; i < ww - 3; i += 3) { GET_ALPHA_3CH_2(); DIV_ALPHA_3CH(); } if (i < ww) { GET_ALPHA_3CH_2_NF(); DIV_ALPHA_3CH_NF(); } } } else { /* if (channel == 2) */ #pragma pipeloop(0) for (i = 0; i < ww; i++) {