Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Mac > OOP Powerplant for Mac > Re: How to rota...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 7 of 7 Topic 453 of 484
Post > Topic >>

Re: How to rotate text using QuickTime API

by David Phillip Oster <oster@[EMAIL PROTECTED] > May 20, 2006 at 03:43 AM

In article <1148034841.120842.143200@[EMAIL PROTECTED]
>,
 "Neel" <nilesh_ibmr@[EMAIL PROTECTED]
> wrote:

> Can we have simple API which does the same thing ?

A quick check of http://groups.google.com/
shows I answered this same 
question in June of 2003. I've revised the code, because, in modern OS 
X, PicHandles are no longer handles (You can't call SetHandleSize() on 
them).

Here is the revised code:

// CText90View.h  

#ifndef _H_CText90View
#define _H_CText90View
#pragma once

#include <LTextEditView.h>

class StScaledUpGWorld{
   GWorldPtr   mSaveGWorld;
   GDHandle mSaveGD;
   GWorldPtr   mGW;
   SInt32      mScaleFactor;
public:
            StScaledUpGWorld(){  mGW = NULL; mScaleFactor = 4; }
            StScaledUpGWorld(GraphicsIm****tComponent inGIC, long 
scaleFactor = 1);
            StScaledUpGWorld(PicHandle ph, long scaleFactor = 1);
            ~StScaledUpGWorld();
   operator GWorldPtr () { return mGW; }
   GWorldPtr   Release();
   void     Rotate90();
   void     Adopt(GWorldPtr inGW, GWorldPtr saveGW, GDHandle saveGD);
   void     Draw(GWorldPtr gw = NULL, GDHandle gd = NULL);
private:
   void     Init(GraphicsIm****tComponent inGIC, long scaleFactor);
   void     Init(PicHandle ph, long scaleFactor);
   void     Die();
};


class StPicHandle{
   PicHandle mPH;
public:
               StPicHandle(PicHandle inPH);
               ~StPicHandle();
      operator PicHandle(){ return mPH; }
      PicHandle   Release();
      void     Adopt(PicHandle inPH);
};


class CText90View : public LTextEditView {
public:
         enum { class_ID = FOUR_CHAR_CODE('TxtV') };
   
                     CText90View( LStream* inStream );
                     
   virtual              ~CText90View();
   
   virtual void         UserChangedText();
   virtual void         DrawSelf();
   virtual void         PrintPanelSelf(const PanelSpec&  inPanel);

         Boolean        IsDirty() const
                        {
                           return mIsDirty;
                        }
                        
         void        SetDirty(
                        Boolean        inDirty)
                        {
                           mIsDirty = inDirty;
                        }
         
protected:
         bool        mIsDirty;

private:
                     CText90View();
                     CText90View(const CText90View& inOriginal);
         CText90View&      operator=(const CText90View& inRhs);
         PicHandle GetAsPict(const Rect& r); // caller must KillPicture
         StPicHandle       mPh;
         StScaledUpGWorld  mGW;
};

void RotateAboutCenter(GraphicsIm****tComponent gic, SInt32 degrees);
void ScaleAboutTopLeft(GraphicsIm****tComponent gic, SInt32 scaleFactor);
PicHandle ScaleAboutTopLeft(PicHandle inPH, SInt32 scaleFactor);
PicHandle CopyPicture(PicHandle inPH);

#endif // _H_CText90View

// CText90View.cp -draws text rotated by 90 degrees.
// for printing, it renders to an offscreen GWorld
#include "CText90View.h"
#include <LStream.h>
#include <cstring>
#include <ImageCompression.h>
#include <QuicktimeComponents.h>


// make a GWorld initialized from a GraphicsIm****tComponent. Dispose 
when goes out of scope.
StScaledUpGWorld::StScaledUpGWorld(GraphicsIm****tComponent inGIC, long 
scaleFactor){
   try{
      Init(inGIC, scaleFactor);
   }catch(...){
      Die();
      throw;
   }
}

// make a GWorld initialized from a PicHandle. Dispose when goes out of 
scope.
StScaledUpGWorld::StScaledUpGWorld(PicHandle ph, long scaleFactor){
   try{
      Init(ph, scaleFactor);
   }catch(...){
      Die();
      throw;
   }
}


void StScaledUpGWorld::Init(GraphicsIm****tComponent inGIC, long 
scaleFactor){
   GetGWorld(&mSaveGWorld, &mSaveGD);
   mGW = NULL;
   mScaleFactor = scaleFactor;
   Rect  r;
   ThrowIfOSStatus_(GraphicsIm****tGetBoundsRect(inGIC, &r));
   try{
      StDisableDebugThrow_();
      ThrowIfOSStatus_(NewGWorld(&mGW, 32, &r, NULL, NULL, 
pixelsLocked));
   }catch(...){
      ThrowIfOSStatus_(NewGWorld(&mGW, 32, &r, NULL, NULL, 
useTempMem|pixelsLocked));
   }
   LockPixels(GetGWorldPixMap(mGW));
   GWorldPtr save****t;
   GDHandle saveDev;
   GetGWorld(&save****t, &saveDev);
   SetGWorld(mGW, NULL);
   EraseRect(&r);
   SetGWorld(save****t, saveDev);
   ThrowIfOSStatus_(GraphicsIm****tSetGWorld(inGIC, mGW, NULL));
   ThrowIfOSStatus_(GraphicsIm****tDraw(inGIC));
   SetGWorld(save****t, saveDev);
}

void StScaledUpGWorld::Init(PicHandle ph, long scaleFactor){
   GetGWorld(&mSaveGWorld, &mSaveGD);
   mGW = NULL;
   mScaleFactor = scaleFactor;
   Rect  r;
   r = (**ph).picFrame;
   try{
      StDisableDebugThrow_();
      ThrowIfOSStatus_(NewGWorld(&mGW, 32, &r, NULL, NULL, 
pixelsLocked));
   }catch(...){
      ThrowIfOSStatus_(NewGWorld(&mGW, 32, &r, NULL, NULL, 
useTempMem|pixelsLocked));
   }
   LockPixels(GetGWorldPixMap(mGW));
   GWorldPtr save****t;
   GDHandle saveDev;
   GetGWorld(&save****t, &saveDev);
   SetGWorld(mGW, NULL);
   EraseRect(&r);
   StHandleLocker lock((Handle) ph);
   DrawPicture(ph, &r);
   SetGWorld(save****t, saveDev);
}


StScaledUpGWorld::~StScaledUpGWorld(){
   Die();
}

void StScaledUpGWorld::Die(){
   if(NULL != mGW){
      SetGWorld(mSaveGWorld, mSaveGD);
      DisposeGWorld(mGW);
   }
}

void StScaledUpGWorld::Draw(GWorldPtr inDestGW, GDHandle gd){
   if(NULL != mGW){
      if(NULL == inDestGW){ inDestGW = mSaveGWorld; }
      if(NULL == gd){ gd = mSaveGD; }
      SetGWorld(inDestGW, gd);
      Rect  bounds;
      Rect  r;
      Get****tBounds(mGW, &bounds);
      r = bounds;
      r.right = r.left + (r.right - r.left)/mScaleFactor;
      r.bottom = r.top + (r.bottom - r.top)/mScaleFactor;

      StColorState   saveColors;
      StColorState::Normalize();
      CopyBits(Get****tBitMapForCopyBits(mGW),
               Get****tBitMapForCopyBits(inDestGW),
               &bounds, &r, ditherCopy, NULL);
   }
}

void StScaledUpGWorld::Adopt(GWorldPtr inGW, GWorldPtr saveGW, GDHandle 
saveGD){
   if(inGW != mGW){
      if(NULL != mGW){
         DisposeGWorld(mGW);
      }
      mGW = inGW;
      mSaveGWorld = saveGW;
      mSaveGD = saveGD;
   }
}

GWorldPtr StScaledUpGWorld::Release(){
   GWorldPtr val = mGW;
   mGW = NULL;
   return val;
}


namespace {
/* ScanLineTranspose - p is a horizontal row of pixels. copy them, down, 
into destPH at x coordinate x.
   n is the number of pixels.
 */
void ScanLineTranspose(Ptr px, SInt32 n, PixMapHandle destPH, SInt32 x){
   unsigned char     *p, *pEnd, *dest;
   SInt32   rowBytes;

   p = reinterpret_cast<unsigned char*>(px);
   dest = reinterpret_cast<unsigned char *>( GetPixBaseAddr(destPH));
   rowBytes = GetPixRowBytes(destPH);
   switch((**destPH).pixelSize){
   case 32:
      pEnd = p + n*4;
      dest += x*4;
      for(; p < pEnd;p += 4, dest += rowBytes){
         * (SInt32*) dest = * (SInt32*) p;
      }
      break;
   default:
      Throw_(paramErr);
      break;
   }
}

}


/* Rotate90 -  90 degrees clockwise.
 */
void StScaledUpGWorld::Rotate90(){
   PixMapHandle   srcPH;
   GWorldPtr      destGW;
   PixMapHandle   destPH;
   Rect        r;
   SInt32         x, y, xMax, yMax, rowBytes;
   Ptr            yp;

   destGW = NULL;
   srcPH = GetGWorldPixMap(mGW); // experiments show: when mem is tight, 
can return NULL!
   if(NULL == srcPH){
      return;
   }
   if( ! LockPixels(srcPH)){
      return;
   }
   r.left = (**srcPH).bounds.top;
   r.top = (**srcPH).bounds.left;
   r.right = (**srcPH).bounds.bottom;
   r.bottom = (**srcPH).bounds.right;
   if(noErr == NewGWorld(&destGW, (**srcPH).pixelSize, &r, 
(**srcPH).pmTable, NULL, 0) ||
      noErr == NewGWorld(&destGW,(**srcPH).pixelSize, &r, 
(**srcPH).pmTable, NULL, useTempMem)){

      destPH = GetGWorldPixMap(destGW);   // experiments show: when mem 
is tight, can return NULL!
      if(NULL == destPH){
         UnlockPixels(srcPH);
         DisposeGWorld(destGW);
         return;
      }
      if( ! LockPixels(destPH)){
         UnlockPixels(srcPH);
         DisposeGWorld(destGW);
         return;
      }
      yp = GetPixBaseAddr(srcPH) ;
      rowBytes = GetPixRowBytes(srcPH);   // mask off flag bits.
      xMax = ((**srcPH).bounds.right - (**srcPH).bounds.left);
      yMax = ((**srcPH).bounds.bottom - (**srcPH).bounds.top);
      for(x = yMax-1, y = 0; y < yMax; y++, x--, yp += rowBytes){
         ScanLineTranspose(yp, xMax, destPH, x);
      }
      UnlockPixels(destPH);
   }
   UnlockPixels(srcPH);
   Adopt(destGW, mSaveGWorld, mSaveGD);
}

// make a GraphicsIm****tComponent initialized from a picFileInMem. 
Dispose when goes out of scope.
class StGraphicsIm****tComponent{
   GraphicsIm****tComponent mGIC;
public:
            explicit StGraphicsIm****tComponent(const FSSpec& inFS);
            explicit StGraphicsIm****tComponent(Handle picFileInMem);
            explicit StGraphicsIm****tComponent(GraphicsIm****tComponent 
inGic){ mGIC = inGic;}
            ~StGraphicsIm****tComponent();
   GraphicsIm****tComponent Release();
   operator GraphicsIm****tComponent(){ return mGIC; }
private:
   void     Init(Handle picFileInMem);
   void     Die();
};

StGraphicsIm****tComponent::StGraphicsIm****tComponent(const FSSpec& inFS)
{
   ThrowIfOSStatus_(GetGraphicsIm****terForFile(&inFS, &mGIC));
}

StGraphicsIm****tComponent::StGraphicsIm****tComponent(Handle 
picFileInMem){
   try{
      Init(picFileInMem);
   }catch(...){
      Die();
   }
}


StGraphicsIm****tComponent::~StGraphicsIm****tComponent()
{
   Die();
}

void StGraphicsIm****tComponent::Init(Handle picFileInMem){
   mGIC = NULL;
   ThrowIfOSStatus_(OpenADefaultComponent(GraphicsIm****terComponentType, 
kQTFileTypePicture, &mGIC));
   ThrowIfOSStatus_(GraphicsIm****tSetDataHandle(mGIC, picFileInMem));
}

void StGraphicsIm****tComponent::Die(){
   if(NULL != mGIC){
      CloseComponent(mGIC);
   }
}

GraphicsIm****tComponent StGraphicsIm****tComponent::Release(){
   GraphicsIm****tComponent val = mGIC;
   mGIC = NULL;
   return val;
}



StPicHandle::StPicHandle(PicHandle inPH) : mPH(inPH){
}

StPicHandle::~StPicHandle(){
   if(NULL != mPH){
      KillPicture(mPH);
   }
}

PicHandle StPicHandle::Release(){
   PicHandle val = mPH;
   mPH = NULL;
   return val;
}

void StPicHandle::Adopt(PicHandle inPH){
   if(inPH != mPH){
      if(NULL != mPH){
         KillPicture(mPH);
      }
      mPH = inPH;
   }
}


class StPicFileFromHandle {
   StHandleBlock  mH;
public:
            StPicFileFromHandle(PicHandle ph);
   operator Handle(){ return mH; }
};

StPicFileFromHandle::StPicFileFromHandle(PicHandle ph) :
   mH(512 + GetHandleSize(reinterpret_cast<Handle>(ph))){
   std::memset(*mH, 0, 512);
   BlockMoveData(*ph, *mH + 512, 
GetHandleSize(reinterpret_cast<Handle>(ph)));
}

// € CText90View    - LStream constructor
CText90View::CText90View(LStream*   inStream) : LTextEditView(inStream), 
mPh(NULL){
   mIsDirty = false;
}


// € ~CText90View Destructor
CText90View::~CText90View(){
}


// € UserChangedText
void CText90View::UserChangedText(){
   if(not IsDirty()){
      SetUpdateCommandStatus(true);
      SetDirty(true);
   }
}

void CText90View::PrintPanelSelf(const PanelSpec&  /*inPanel*/){
   GWorldPtr   saveGW;
   GDHandle saveGD;
   GetGWorld(&saveGW, &saveGD);
   mGW.Draw(GetMac****t(), saveGD);
}


void CText90View::DrawSelf(){
   Rect        r;
   CalcLocalFrameRect(r);
   StPicHandle             ph(GetAsPict(r));
   StPicFileFromHandle        picFile(ph);
   StGraphicsIm****tComponent  gic(picFile);
   RotateAboutCenter(gic, 90);
   ThrowIfOSStatus_(GraphicsIm****tDraw(gic));

   if(NULL == mGW){
      GWorldPtr   saveGW;
      GDHandle saveGD;
      Rect        r;
      CalcLocalFrameRect(r);
      StPicHandle             ph(GetAsPict(r));
      StPicHandle             ph2(ScaleAboutTopLeft(ph, 4));
      StScaledUpGWorld        gw(ph2, 4);
      gw.Rotate90();
      GetGWorld(&saveGW, &saveGD);
      mGW.Adopt(gw.Release(), saveGW, saveGD);
   }
}

void RotateAboutCenter(GraphicsIm****tComponent gic, SInt32 degrees){
   Rect  r;
   MatrixRecord mat;
   ThrowIfOSStatus_(GraphicsIm****tGetMatrix(gic, &mat));
   ThrowIfOSStatus_(GraphicsIm****tGetBoundsRect(gic, &r));
   RotateMatrix(&mat, degrees << 16, 
      static_cast<long>(r.right - r.left) << 15, 
      static_cast<long>(r.bottom - r.top) << 15);
   GraphicsIm****tSetMatrix(gic, &mat);
}

void ScaleAboutTopLeft(GraphicsIm****tComponent gic, SInt32 scaleFactor){
   Rect  r;
   MatrixRecord mat;
   ThrowIfOSStatus_(GraphicsIm****tGetMatrix(gic, &mat));
   ThrowIfOSStatus_(GraphicsIm****tGetBoundsRect(gic, &r));
   ScaleMatrix(&mat, scaleFactor << 16, scaleFactor << 16, 
      static_cast<long>(r.left) << 16, 
      static_cast<long>(r.top) << 16);
   GraphicsIm****tSetMatrix(gic, &mat);
}

// caller must dispose.
PicHandle ScaleAboutTopLeft(PicHandle inPH, SInt32 scaleFactor){
   Rect  r;
   OpenCPicParams    picParams;
   r = (**inPH).picFrame;
   r.right = r.left + (r.right - r.left)*scaleFactor;
   r.bottom = r.top + (r.bottom - r.top)*scaleFactor;

   picParams.srcRect = r;
   picParams.hRes = 0x00480000 * 1;
   picParams.vRes = picParams.hRes;
   picParams.version = 2;
   StPicHandle ph(OpenCPicture(&picParams));
   ClipRect(&r);
   StHandleLocker lock((Handle) inPH);
   DrawPicture(inPH, &r);
   ClosePicture();
   return ph.Release();
}


namespace {

Handle CopyHandle(Handle inH){
   ThrowIfOSErr_(HandToHand(&inH));
   return inH;
}


}

PicHandle CopyPicture(PicHandle inPH){
   return (PicHandle) CopyHandle((Handle) inPH);
}


PicHandle CText90View::GetAsPict(const Rect& r){
   if(NULL != (PicHandle) mPh){
      return CopyPicture(mPh);
   }
   OpenCPicParams    picParams;
   picParams.srcRect = r;
   picParams.hRes = 0x00480000;
   picParams.vRes = picParams.hRes;
   picParams.version = 2;
   // put it in a picture
   StPicHandle ph(OpenCPicture(&picParams));
   LTextEditView::DrawSelf(); 
   ClosePicture();
   mPh.Adopt(CopyPicture(ph));
   return ph.Release();
}
 




 7 Posts in Topic:
Hot to rorate text using QuickTime API
"Neel" <nile  2006-05-18 06:09:09 
Re: Hot to rorate text using QuickTime API
David Phillip Oster <o  2006-05-18 14:35:01 
Re: Hot to rorate text using QuickTime API
david ralley <ralley.2  2006-05-18 10:39:28 
Re: How to rotate text using QuickTime API
David Phillip Oster <o  2006-05-20 02:46:20 
Re: Hot to rorate text using QuickTime API
"Neel" <nile  2006-05-19 02:26:50 
Re: Hot to rorate text using QuickTime API
"Neel" <nile  2006-05-19 03:34:01 
Re: How to rotate text using QuickTime API
David Phillip Oster <o  2006-05-20 03:43:13 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Fri Dec 5 10:12:15 CST 2008.