//****************************************** VOID BIT_VECTOR::set_len( USHORT len) //in { ThrowIf_(len>max_len); ThrowIf_(len<1); its_len = len; }
//****************************************** BIT_VECTOR::BIT_VECTOR( USHORT len /*=1*/, //in USHORT dec_rep /*=0*/) //in :its_len(len), its_dec_rep(dec_rep) { ThrowIf_(len>max_len); ThrowIf_(len<1); }
//****************************************** USHORT lazy_from_normal( USHORT normal, //in USHORT bit_len) //in { ThrowIf_(normal>= (1<<bit_len)); ThrowIf_(bit_len>BIT_VECTOR::max_len); USHORT lazy = normal; for(SHORT m = (SHORT)bit_len-2; m >= 0; m--){ //Look at bpos = m+1, if it's ON, then flip bpos=m. //Remember that ^ is same as a mod2 sum. lazy ^= ( (((1 << m+1) & normal)?1:0) << m ); } return lazy; }
//****************************************** VOID BIT_VECTOR::normal_to_lazy( const BIT_VECTOR & normal_bvec, //in BIT_VECTOR & lazy_bvec) //out { ThrowIf_(lazy_bvec.its_len != normal_bvec.its_len); lazy_bvec.its_dec_rep = lazy_from_normal(normal_bvec.its_dec_rep, normal_bvec.its_len); }
//****************************************** BOOLEAN BIT_VECTOR::bit_is_ON( USHORT bpos) //in const { ThrowIf_(bpos>=its_len); USHORT mask = (1<<bpos); return (its_dec_rep & mask)==mask; }
//****************************************** VOID PERMUTATION::pre_multiply_by( const PERMUTATION & p) //in { //this is similar to the operation *= //except that * for permutations is not commutative ThrowIf_(p.its_len != its_len); for(USHORT j=0; j<its_len; j++){ its_array_p[j] = p.its_array_p[its_array_p[j]]; } }
//****************************************** VOID PERMUTATION::set_to_identity( USHORT len) { ThrowIf_(len==0); if(len != its_len){ delete its_array_p; its_array_p= new USHORT [len];//new[] its_len = len; } set_to_identity(); }
/*============================================ SUMiscUtils::DuplicateHandle ==============================================*/ Handle SUMiscUtils::DuplicateHandle( Handle source ) { ThrowIf_ ( !source || !*source ); SInt32 numBytes = GetHandleSize( source ); Handle result = NewHandle( numBytes ); ThrowIfMemFail_( result ); BlockMoveData( *source, *result, numBytes ); return( result ); }
//****************************************** PERMUTATION operator *( const PERMUTATION & p2, //in const PERMUTATION & p1) //in { //permutation product is function composition ThrowIf_(p1.its_len != p2.its_len); USHORT len = p1.its_len; PERMUTATION p(len); for(USHORT j=0; j<len; j++){ p.its_array_p[j] = p2.its_array_p[p1.its_array_p[j]]; } return p; }
//****************************************** USHORT BIT_VECTOR::permute_bits( const PERMUTATION & pmut) //in { ThrowIf_(its_len!=pmut.get_len()); USHORT dec=0; for(USHORT i=0; i<its_len; i++){ if( ((its_dec_rep>>i)&1)==1 ){ dec |= (1<<pmut[i]); } } its_dec_rep = dec; return dec; }
//****************************************** VOID BIT_VECTOR::lazy_advance( USHORT new_normal) //in { //This method takes bit vector "lazy" (which corresponds to bit vector "normal"), and //changes it to the next lazy bit vector, "new_lazy" (which corresponds to "new_normal"). ThrowIf_(new_normal<1); its_dec_rep ^= ((new_normal) & ~(new_normal-1)); //example: 000, 001, 011, 010, 110, 111, 101, 100 //its_dec_rep = 011, normal = 2 = 010 initially //new_normal = 3 = 011 //(new_normal & ~normal) = 011 & 101 = 001 = mask for the bit that changed //its_dec_rep = 011 ^ 001 = 010 finally }
//****************************************** VOID nu_to_n1_vec( USHORT num_of_bits, //in VECTOR<DOUBLE> & in_vec) //io { //As in Latex, let _beta mean a subscript of beta. //For bit beta, define //n(beta) = diag(0,1)_beta, //u(beta) = nbar(beta) = 1 - n(beta) = diag(1,0)_beta //1_beta = diag(1,1)_beta //This method replaces in_vec (a vector from the n,u basis) by //its equivalent in the n,1 basis //example: //2 bits //A00 u(1)u(0) = A00 [ ( 1)*1 + (-1)*n(0) + (-1)*n(1) + ( 1)*n(1)n(0) ] //A01 u(1)n(0) = A01 [ ( 0)*1 + ( 1)*n(0) + ( 0)*n(1) + (-1)*n(1)n(0) ] //A10 n(1)u(0) = A10 [ ( 0)*1 + ( 0)*n(0) + ( 1)*n(1) + (-1)*n(1)n(0) ] //A11 n(1)n(0) = A11 [ ( 0)*1 + ( 0)*n(0) + ( 0)*n(1) + ( 1)*n(1)n(0) ] //vector in n,u basis: [A00, A01, A10, A11] //vector in n,1 basis: [B00, B01, B10, B11] //where //B00 = A00*( 1) //B01 = A00*(-1) + A01*( 1) //B10 = A00*(-1) + A01*( 0) + A10*( 1) //B11 = A00*( 1) + A01*(-1) + A10*(-1) + A11*( 1) if(num_of_bits==0)return;//do nothing since only one component USHORT num_of_comps = (1 << num_of_bits); ThrowIf_(in_vec.get_len()!=num_of_comps); VECTOR<DOUBLE> n1_vec(0, num_of_comps); BIT_VECTOR bvec(num_of_bits, 0); for(USHORT i_n1=0; i_n1<num_of_comps; i_n1++){ for(USHORT i_nu=0; i_nu<=i_n1; i_nu++){ if( (i_nu & i_n1)==i_nu ){ //remember that i^j is bitwise mod2 addition of i and j bvec.set_dec_rep(i_nu ^ i_n1); if(bvec.get_num_of_ON_bits()%2){//bvec.num_of_ON_bits is odd n1_vec[i_n1] -= in_vec[i_nu]; }else{//bvec.num_of_ON_bits is even n1_vec[i_n1] += in_vec[i_nu]; } } } } in_vec = n1_vec; }
/*=================================== SwapUndoState ====================================*/ void PTPaintView::SwapUndoState() { ThrowIf_( !mCurrentImage || !mUndoBuffer || !mScratchBuffer || !mCanvas ); SUOffscreen *tempOffscreen = mCurrentImage; mCurrentImage = mUndoBuffer; mUndoBuffer = tempOffscreen; PTPaintSelection *tempSelection = mCurrentSelection; mCurrentSelection = mUndoSelection; mUndoSelection = tempSelection; this->SetChangedFlag( true ); this->HandleCanvasDraw(); this->RedrawSampleView( nil ); }
//****************************************** BOOLEAN BIT_VECTOR::find_ON_bit_to_my_right( USHORT me_bit, //in USHORT & right_ON_bit) //out { ThrowIf_(me_bit>=its_len); if(me_bit==0)return false; right_ON_bit = me_bit; USHORT mask = (1<<right_ON_bit); BOOLEAN found_it = false; do{ right_ON_bit--; mask >>= 1; found_it = ((its_dec_rep & mask) == mask); }while( (right_ON_bit!=0) && !found_it ); return found_it; }
//****************************************** BOOLEAN BIT_VECTOR::find_ON_bit_to_my_left( USHORT me_bit, //in USHORT & left_ON_bit) //out { ThrowIf_(me_bit>=its_len); if(me_bit==(its_len-1))return false; left_ON_bit = me_bit; USHORT mask = (1<<left_ON_bit); BOOLEAN found_it = false; do{ left_ON_bit++; mask <<= 1; found_it = ((its_dec_rep & mask) == mask); }while( (left_ON_bit!=(its_len-1)) && !found_it ); return found_it; }
//****************************************** BOOLEAN PERMUTATION::dict_advance() { //dict = dictionary //In dictionary ordering, //first permutation is the identity permutation //(pmut[0]=0, pmut[1]=1, etc. ). //This method advances the permutation to //the next permutation in dictionary ordering. //It returns false if we've reached the last one. //Otherwise it returns true. //Ref:book "Combinatorial Generation", by Joe Sawada /* Example 04321 step:14320 step:10324 step:10234 */ SHORT k, j; SHORT s, r; ThrowIf_(its_len<=1); k = its_len - 2; while(its_array_p[k] > its_array_p[k+1]){ k--; if(k==-1)break; } if (k == -1){ return false; }else{ j = its_len - 1; while(its_array_p[k] > its_array_p[j]){ j--; } swap_entries(j, k); s = k+1; r = its_len - 1; while(s<r){ swap_entries(r, s); s++; r--; } } return true; }
/*================================== SaveAsResource ===================================*/ void PTCursorView::SaveAsResource( RFMap *inMap, ResIDT inResID ) { Handle h = nil; ThrowIf_( !mBWSample || !mMaskSample ); SUOffscreen *bwBuffer = mBWSample->GetBuffer(); SUOffscreen *maskBuffer = mMaskSample->GetBuffer(); Point theHotSpot = mCanvas->GetHotSpot(); try { switch( mResourceType ) { case ImageType_Cursor: h = this->CreateBWCursor( bwBuffer, maskBuffer, theHotSpot ); break; case ImageType_ColorCursor: ThrowIfNil_( mColorSample ); h = this->CreateColorCursor( mColorSample->GetBuffer(), bwBuffer, maskBuffer, theHotSpot ); break; default: LException::Throw( err_InvalidImageFormat ); } RFResource *theResource = inMap->FindResource( mResourceType, inResID, true ); ThrowIfNil_( theResource ); theResource->SetResData( h ); } catch( ... ) { SUMiscUtils::DisposeHandle( h ); throw; } this->SetChangedFlag( false ); SUMiscUtils::DisposeHandle( h ); }
//****************************************** BOOLEAN BIT_VECTOR::find_lazy_leftmost_ON_bit( USHORT new_normal, //in USHORT & leftmost_ON_bit) //out { //This method works only for bit vectors in the standard lazy sequence. //example: 000, 001, 011, 010, 110, 111, 101, 100 //if new_normal >= 4, leftmost_ON_bit = 2 //else if new_normal >= 2, leftmost_ON_bit = 1 //else if new_normal >= 1, leftmost_ON_bit = 0 ThrowIf_(new_normal<1); BOOLEAN found_it = true; if(its_dec_rep == 0){ found_it = false; }else{ for(SHORT n=its_len-1; n>=0; n--){ if(new_normal >= (1<< n)){ leftmost_ON_bit = n; break; } } } return found_it; }
//****************************************** VOID had_transform( USHORT num_of_bits, //in VECTOR<DOUBLE> & in_vec) //io { //This method replaces in_vec by its Hadamard transform. if(num_of_bits==0)return;//do nothing since only one component USHORT num_of_comps = (1 << num_of_bits); ThrowIf_(in_vec.get_len()!=num_of_comps); VECTOR<DOUBLE> prev_vec; LONG half_num_of_comps = (1 << (num_of_bits - 1)); for(USHORT beta=0; beta < num_of_bits; beta++){ USHORT j = 0; prev_vec = in_vec; for(USHORT i=0; i < half_num_of_comps; i++){ DOUBLE x = prev_vec[j]; DOUBLE y = prev_vec[j + 1]; in_vec[i]= x + y; in_vec[half_num_of_comps + i] = x - y; j +=2; } } }
//****************************************** BOOLEAN PERMUTATION::rev_dict_advance() { //rev_dict = reverse dictionary //In reverse dictionary ordering, //last permutation is the identity permutation //(pmut[0]=0, pmut[1]=1, etc. ). //This method advances the permutation to //the next permutation in reverse dictionary ordering. //It returns false if we've reached the last one. //Otherwise it returns true. //see PERMUTATION::dict_advance() SHORT k, j; SHORT s, r; ThrowIf_(its_len<=1); k = its_len - 2; while(its_array_p[its_len -1 - k] > its_array_p[its_len -2 - k]){ k--; if(k==-1)break; } if (k == -1){ return false; }else{ j = its_len - 1; while(its_array_p[its_len -1 - k] > its_array_p[its_len -1 - j]){ j--; } swap_entries(its_len -1 - j, its_len -1 - k); s = k+1; r = its_len - 1; while(s<r){ swap_entries(its_len -1 - r, its_len -1 - s); s++; r--; } } return true; }
void PDContainer::SetRMMap( RMMap* inRMMap) { // Do pointer sanity checks. ValidateThis_(); ValidateObject_(inRMMap); // don't validate: map is a contained object // Make sure that this method hasn't been called before. ThrowIf_(mRMMap != nil); // Link container to low-level resource map. mRMMap = inRMMap; mRMMap->AddListener(this); // Now that we have the map, build source control. BuildSCCObject(); }
/*=============================================== ChangeImageSize Note: Affects only the pixpat, _not_ the black & white pattern. ================================================*/ void PTPatternView::ChangeImageSize( SInt32 inWidth, SInt32 inHeight, Boolean inStretch ) { ThrowIf_( (inWidth < mMinImageWidth) || (inHeight < mMinImageHeight) ); ThrowIf_( (inWidth > mMaxImageWidth) || (inHeight > mMaxImageHeight) ); ThrowIf_( mResourceType != ImageType_PixPat ); ThrowIfNil_( mColorSample ); ThrowIfNil_( mCurrentImage ); SInt32 savedWidth = mPixPatWidth; // in case of error... SInt32 savedHeight = mPixPatHeight; Boolean changedSize = true; SUOffscreen *newBuffer = nil; Rect destR; try { /***************************************** create a new buffer -- same depth as current one, but new size *****************************************/ newBuffer = mCurrentImage->CreateSimilarOffscreen( false, inWidth, inHeight ); /***************************************** copy the image from the old buffer into the new one *****************************************/ if ( inStretch ) ::SetRect( &destR, 0, 0, inWidth, inHeight ); else ::SetRect( &destR, 0, 0, mCurrentImage->GetWidth(), mCurrentImage->GetHeight() ); newBuffer->CopyFrom( mCurrentImage, &destR ); /***************************************** resize the pixpat sample pane *****************************************/ this->ResizeSampleWell( inWidth, inHeight ); changedSize = true; /***************************************** keep track of the changed size. do this before SetImage() because it may call GetZoomFactor. *****************************************/ mPixPatWidth = inWidth; mPixPatHeight = inHeight; /***************************************** set the current buffer -- this can trigger all sorts of things (canvas resize, etc) *****************************************/ this->SetImage( newBuffer, PTResize_All, redraw_Later ); /***************************************** change the sample pane's buffer. Notes: (1) The sample pane will own the buffer after this call (don't delete it) (2) The previous sample pane buffer will be saved away by the PTResizer object *****************************************/ mColorSample->SetRawBuffer( newBuffer ); } catch( ... ) { /* restore things to the way they were before we were called */ mPixPatWidth = savedWidth; mPixPatHeight = savedHeight; if ( changedSize ) this->ResizeSampleWell( mPixPatWidth, mPixPatHeight ); delete newBuffer; throw; } }
/*================================= DoSizeDialog ==================================*/ Boolean PTFontSizeDialog::DoSizeDialog( SInt16 inSize, SInt16 *outSize ) { try { /*************************** ensure that the window is created properly (Window Mgr bug) ****************************/ StSaveGWorld aSaver; ::SetGDevice( ::GetMainDevice() ); /*************************** create the dialog ****************************/ StApplicationContext appContext; // must load from application file StDialogHandler theHandler( PPob_TextSizeDialog, LCommander::GetTopCommander() ); LWindow * theWindow = theHandler.GetDialog(); LEditText * sizeField = dynamic_cast<LEditText*> (theWindow->FindPaneByID( PaneID_Size )); ThrowIf_( !sizeField ); /******************************************** initialize the values & show the window ********************************************/ sizeField->SetValue( inSize ); theWindow->Show(); /******************************************** go into an event loop ********************************************/ Boolean done = false; MessageT theMessage; SInt16 newSize; while( !done ) { theMessage = theHandler.DoDialog(); if ( theMessage == msg_Cancel ) done = true; else if ( theMessage == msg_OK ) { newSize = sizeField->GetValue(); if ( (newSize < 4) || (newSize > 512) ) { theWindow->SwitchTarget( sizeField ); sizeField->SelectAll(); SUErrors::DisplayError( err_BadFontSize ); } else done = true; } }; /******************************************** return values to the caller ********************************************/ if ( theMessage == msg_OK ) { *outSize = newSize; return( true ); } else return( false ); } catch( ... ) { SUErrors::DisplayError( err_Generic ); return( false ); } }
/*==================================== GetFamilyMemberInfo index is 1..n =====================================*/ void PTFamilyView::GetFamilyMemberInfo( SInt32 index, PaintFamilyMember *oRec ) { ThrowIf_( (index <= 0) || (index > (**mFamilyListH).numEntries) ); *oRec = (**mFamilyListH).members[ index - 1 ]; }
//****************************************** VOID BIT_VECTOR::set_bit_OFF( USHORT bpos) //in { ThrowIf_(bpos>=its_len); its_dec_rep &= ~(1<<bpos); }
/*================================== CreateColorCursor Note: See description of CCrsr structure above. ===================================*/ Handle PTCursorView::CreateColorCursor( SUOffscreen *inColor, SUOffscreen *inBW, SUOffscreen *inMask, Point inHotSpot ) { Handle h = nil; Boolean deleteBuffer = false; ThrowIf_( !inColor || !inBW || !inMask ); try { /********************************** downsample the color buffer to a more reasonable depth **********************************/ if ( inColor->GetDepth() >= 16 ) { inColor = SUColorTableBuilder::DownSampleBuffer( inColor, 8, // max depth false, // don't force b&w into table true, // minimize table true ); // use larger inverse table ThrowIfNil_( inColor ); // shouldn't happen deleteBuffer = true; // since we created it } /********************************** Get the color table from the color buffer **********************************/ CTabHandle sourceTable = inColor->GetColorTable(); ThrowIfNil_( sourceTable ); SInt32 colorTableBytes = ::GetHandleSize( (Handle) sourceTable ); /********************************** do some calculations **********************************/ SInt32 depth = inColor->GetDepth(); SInt32 pixelRowBytes = SUColorUtils::CalcRowBytes( Cursor_Width, depth ); SInt32 pixelBytes = pixelRowBytes * Cursor_Height; SInt32 totalBytes = sizeof( CCrsr) + sizeof( PixMap ) + colorTableBytes + pixelBytes; SInt32 offsetToPixmap = sizeof(CCrsr); SInt32 offsetToPixelData = sizeof(CCrsr) + sizeof(PixMap); SInt32 offsetToColorTable = sizeof(CCrsr) + sizeof(PixMap) + pixelBytes; /********************************** Allocate the cursor **********************************/ h = ::NewHandleClear( totalBytes ); ThrowIfMemFail_( h ); ::HLock( h ); CCrsr *p = (CCrsr *) *h; PixMap *theMap = (PixMap*) (*h + offsetToPixmap); /********************************** Fill up the structure (note: fields are already zeroed) **********************************/ p->crsrType = 0x8001; // magic number for cursors p->crsrMap = (PixMapHandle) offsetToPixmap; p->crsrData = (Handle) offsetToPixelData; inBW->CopyToRawData( (UInt8*) &p->crsr1Data, BWCursor_RowBytes ); inMask->CopyToRawData( (UInt8*) &p->crsrMask, BWCursor_RowBytes ); p->crsrHotSpot = inHotSpot; theMap->rowBytes = 0x8000 + pixelRowBytes; ::SetRect( &theMap->bounds, 0, 0, Cursor_Width, Cursor_Height ); theMap->hRes = 0x00480000; theMap->vRes = 0x00480000; theMap->pixelSize = depth; theMap->cmpCount = 1; theMap->cmpSize = depth; theMap->pmTable = (CTabHandle) offsetToColorTable; inColor->CopyToRawData( (UInt8*)( *h + offsetToPixelData ), pixelRowBytes ); CTabPtr destTable = (CTabPtr) (*h + offsetToColorTable); BlockMoveData( *sourceTable, destTable, colorTableBytes ); destTable->ctFlags = 0; // 0 for pixmaps, 0x8000 for devices } catch( ... ) { if ( deleteBuffer && inColor ) delete inColor; SUMiscUtils::DisposeHandle( h ); throw; } if ( deleteBuffer && inColor ) delete inColor; ::HUnlock( h ); return( h ); }