Adjust Width of Core Text Tab - objective-c

I am fairly new to Core Text but have been getting on well, however I'm having trouble adjusting the width of a tab.
Currently I'm using this code which I have written by looking at the documentation and mailing list:
CFIndex theNumberOfSettings = 1;
CFIndex i = 0;
CTTextTabRef tabArray[1];
CTTextAlignment align = 0;
CGFloat location = 80;
for (;i < 1; i++ ) {
tabArray[i] = CTTextTabCreate( align, location, NULL );
}
CFArrayRef tabStops = CFArrayCreate( kCFAllocatorDefault, (const void**) tabArray, 1, &kCFTypeArrayCallBacks );
for (;i < 1; i++ ) { CFRelease( tabArray[i] ); }
CTParagraphStyleSetting theSettings[1] =
{
{ kCTParagraphStyleSpecifierTabStops, sizeof(CFArrayRef), &tabStops },
};
CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(theSettings, theNumberOfSettings);
[self.attributedString addAttribute:(NSString *)kCTParagraphStyleAttributeName
value:(id)paragraphStyle
range:range];
By setting the value of location I am able to adjust the width of the tab however this only works for the first tab created after that it resets to a different width which is very small comparatively.
Why is it doing this?

I would imagine the issue is all your tabs are created with the exact same location. Each one should probably be a multiple of 80, rather than being exactly 80.

Related

Directx11 heightmap texture real-time modification problem

I'm making a terrain tool.
I made a 2D texture and am using it as a height map.
I want to change a specific part of the heightmap, but I'm having a problem.
I changed certain small parts, but the whole landscape of the texture is changed.
I would like to know the cause of this problem and how to solve it
thank you.
`HeightMap ShaderResourceView Create Code
void TerrainRenderer::BuildHeightmapSRV(ID3D11Device* device)
{
ReleaseCOM(mHeightMapSRV);
ReleaseCOM(m_hmapTex);
D3D11_TEXTURE2D_DESC texDesc;
texDesc.Width = m_terrainData.HeightmapWidth; //basic value 2049
texDesc.Height = m_terrainData.HeightmapHeight; //basic value 2049
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R16_FLOAT;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DYNAMIC;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
texDesc.MiscFlags = 0;
// HALF is defined in xnamath.h, for storing 16-bit float.
std::vector<HALF> hmap(mHeightmap.size());
//current mHeightmap is all zero.
std::transform(mHeightmap.begin(), mHeightmap.end(), hmap.begin(), XMConvertFloatToHalf);
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = &hmap[0];
data.SysMemPitch = m_terrainData.HeightmapWidth * sizeof(HALF);
data.SysMemSlicePitch = 0;
HR(device->CreateTexture2D(&texDesc, &data, &m_hmapTex));
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = texDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = -1;
HR(device->CreateShaderResourceView(m_hmapTex, &srvDesc, &mHeightMapSRV));
}
`HeightMap Texture modifying code
D3D11_MAPPED_SUBRESOURCE mappedData;
//m_hmapTex is ID3D11Texture2D*
HR(m_texMgr.m_context->Map(m_hmapTex, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_WRITE_DISCARD, 0, &mappedData));
HALF* heightMapData = reinterpret_cast<HALF*>(mappedData.pData);
D3D11_TEXTURE2D_DESC heightmapDesc;
m_hmapTex->GetDesc(&heightmapDesc);
UINT width = heightmapDesc.Width;
for (int row = 0; row < width/4; ++row)
{
for (int col = 0; col < width/4; ++col)
{
idx = (row * width) + col;
heightMapData[idx] = static_cast<HALF>(XMConvertFloatToHalf(200));
}
}
m_texMgr.m_context->Unmap(m_hmapTex, D3D11CalcSubresource(0,0,1));
Please refer to the picture below
The lower right area renders the HeightMap texture.
I wanted to edit only 1/4 width and height, but that's all changed.
enter image description here
When the completed heightmap is applied, it works normally.
enter image description here
A texture does not always have the same width and height in memory as the definition suggests. Some textures strides (lines) are oversized. You have to use the Stride Size * Row to calculate the offset to write into.

Debug Assertion Failed with rgbConverted.cpp

First saying, It's a duplicate question, but not the same problem.
When I run my code, this message is showing, but no error.
#pragma once
using namespace System::Drawing;
ref class rgbConvert
{
private:
System::Drawing::Bitmap^ grayImage;
System::Drawing::Bitmap^ bainaryImage;
System::Drawing::Bitmap^ rgbImage;
int xsize;
int ysize;
bool **BArray;
int **GrayArray;
int **binary;
FILE *fp;
static float coef01 = (float)0.2989;
static float coef02 = (float)0.5870;
static float coef03 = (float)0.1140;
public:
rgbConvert(System::Drawing::Bitmap^ im)
{
rgbImage = im;
xsize = rgbImage->Height;
ysize = rgbImage->Width;
}
rgbConvert(int height, int width)
{
xsize = height;
ysize = width;
}
int** getGrayImageArray ()
{
GrayArray = new int * [xsize];
for (int i = 0; i < xsize; i++ )
{
GrayArray[i] = new int[ysize];
}
for( int i = 0; i < this->xsize; i++ )
{
for ( int j = 0; j < this->ysize; j++ )
{
System::Drawing::Color^ clr = this->rgbImage->GetPixel(j, i);
int pixel = clr->ToArgb();
//int alpha = (pixel >> 24) & 0xff;// no need here
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel ) & 0xff;
int grayC = int(coef01*red + coef02*green + coef03*blue);
GrayArray[i][j] = grayC;
}// inner for*/
}
return GrayArray;
}
void getGrayImageArray (int** gArray)
{
this->GrayArray = gArray;
}
bool** GetBinaryArray( int level )
{
BArray = new bool * [xsize];
for (int i = 0; i < xsize; i++ )
{
BArray[i] = new bool[ysize];
}
binary = new int * [xsize];
for (int i = 0; i < xsize; i++ )
{
binary[i] = new int[ysize];
}
fp=fopen("C:\\binary.txt","w");
int grayC;
for ( int xVal = 0; xVal < xsize; xVal++ )
{
for( int yVal = 0; yVal < ysize; yVal++ )
{
grayC = GrayArray[xVal][yVal];
if ( grayC >= level )
{
BArray[xVal][yVal] = true;
binary[xVal][yVal] = 1;
fprintf(fp,"%d",binary[xVal][yVal]);
}
else
{
BArray[xVal][yVal] = false;
binary[xVal][yVal] = 0;
fprintf(fp,"%d",binary[xVal][yVal]);
}
}// inner for*/
}
fclose(fp);
return BArray;
}
};
When I press Retry, then breakpoint showing this line.
fprintf(fp,"%d",binary[xVal][yVal]);
If I remove these lines then showing breakpoint in main program.
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}
Breakpoint showing in return 0 this line.
Actually this is a well known problem. I have already solved this topics. In my code I had created text files, docx files and images in C drives. But there was no permission for accessing C drive in my computer.
Then I had solved by following this steps:
If you can access cmd, you can reset the security settings in
Vista/Windows 7 with the following command: "secedit /configure /cfg
%windir%\inf\defltbase.inf /db defltbase.sdb /verbose" (no quotes.)
To see what this command does, go here: How do I restore security
settings to the default settings?
NOTE: If you can't access cmd when logged in, use this guide
System Recovery Options. You can get to the command line when you
access the System Recovery Options screen.
This command seems to give the ownership issue a kick up the
backside, even though it seems nothing has changed. Go to Explorer,
right click on C: and go to Properties.
Go to the Security tab and then Advanced.
Go to the Owner tab. Now you should be able to click Edit.
If you don't have Administrators in the list under where it says
"Change owner to:" then go to "Other users or groups". If you do, go
straight to step 7.
On Others users or groups type in "Administrators" (no quotes) in
the bottom box. Click Check Name and then OK.
Click Administrators and then OK. You've now given yourself
ownership of C:! (As long as your account is an Administrator, that
is.)
Click OK on the "Advanced Security Settings..." window to get back
to the Properties window. You should now have a list of the
Permissions and so on where before you only had something about how
you couldn't view permissions. Progress, eh?
You may need to add in the Adminstrators group to edit their
permissions. To do this, click "Edit" and then "Add" and type
"Administrators" (no quotes) in the bottom box. Then hit Check Name
and then OK.
Click Administrators in the list and tick the box in the Allow
column next to "Full control".
Click Apply, you'll likely get a bunch of error messages about how
this can't be applied to some files and folders. Just OK through
them all. Once done, you should have access to your C: drive once
more!
Source Link

Check if image is dark-only bottom part

I am checking if UIImage is darker or more whiter . I would like to use this method ,but only to check the third bottom part of the image ,not all of it .
I wonder how exactly to change it to check that,i am not that familiar with the pixels stuff .
BOOL isDarkImage(UIImage* inputImage){
BOOL isDark = FALSE;
CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(inputImage.CGImage));
const UInt8 *pixels = CFDataGetBytePtr(imageData);
int darkPixels = 0;
long length = CFDataGetLength(imageData);
int const darkPixelThreshold = (inputImage.size.width*inputImage.size.height)*.25;
//should i change here the length ?
for(int i=0; i<length; i+=4)
{
int r = pixels[i];
int g = pixels[i+1];
int b = pixels[i+2];
//luminance calculation gives more weight to r and b for human eyes
float luminance = (0.299*r + 0.587*g + 0.114*b);
if (luminance<150) darkPixels ++;
}
if (darkPixels >= darkPixelThreshold)
isDark = YES;
I can just crop that part of the image, but this will be not efficient way, and wast time .
The solution marked correct here is a more thoughtful approach for getting the pixel data (more tolerant of differing formats) and also demonstrates how to address pixels. With a small adjustment, you can get the bottom of the image as follows:
+ (NSArray*)getRGBAsFromImage:(UIImage*)image
atX:(int)xx
andY:(int)yy
toX:(int)toX
toY:(int)toY {
// ...
int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
int byteIndexEnd = (bytesPerRow * toY) + toX * bytesPerPixel;
while (byteIndex < byteIndexEnd) {
// contents of the loop remain the same
// ...
}
To get the bottom third of the image, call this with xx=0, yy=2.0*image.height/3.0 and toX and toY equal to the image width and height, respectively. Loop the colors in the returned array and compute luminance as your post suggests.

elliptical fixture in box2d and cocos2d

I am trying to develop an iOS game in Cocos2d + Box2d. I want to use elliptical fixtures in Box2D. I tried using b2Capsule shape, but its not exactly what I want as the collision is not proper. Anyone has done this before?
For specific shapes in Box2D you will have to triangulate you original polygon (in your case an ellipse in which you keep a certain number of vertices).
For this, you can use the poly2tri excellent constrained Delaunay triangulation at http://code.google.com/p/poly2tri/
It is very simple. Here is the way I get my triangles :
- (NSArray*) triangulate:(NSArray*)verticesArray
{
NSMutableArray* outputTriangles = [[[NSMutableArray alloc] init] autorelease];
p2t::CDT* triangulationContainer;
vector<p2t::Triangle*> p2tTriangles;
vector< vector<p2t::Point*> > polylines;
vector<p2t::Point*> polyline;
for (hOzPoint2D *point in verticesArray) {
polyline.push_back(new p2t::Point([point x], [point y]));
}
polylines.push_back(polyline);
triangulationContainer = new p2t::CDT(polyline);
triangulationContainer->Triangulate();
p2tTriangles = triangulationContainer->GetTriangles();
for (int i = 0; i < p2tTriangles.size(); i++) {
p2t::Triangle& t = *p2tTriangles[i];
p2t::Point& a = *t.GetPoint(0);
p2t::Point& b = *t.GetPoint(1);
p2t::Point& c = *t.GetPoint(2);
[outputTriangles addObject:[NSArray arrayWithObjects:
[hOzPoint2D point2DWithDoubleX:a.x doubleY:a.y],
[hOzPoint2D point2DWithDoubleX:b.x doubleY:b.y],
[hOzPoint2D point2DWithDoubleX:c.x doubleY:c.y], nil]];
}
delete triangulationContainer;
for(int i = 0; i < polylines.size(); i++) {
vector<p2t::Point*> poly = polylines[i];
FreeClear(poly);
}
return [outputTriangles copy];
}
hOzPoint2D here is my custom point class, but you can pass any couple of coordinates. You don't even have to output a NSArray : you can insert this method in your body creation one.
Be careful that poly2tri has some restrictions :
you can't have twice the same point in your polygon ;
the polygon must not be self-intersecting ;
...
Read the poly2tri page to know more.
The resulting array contains triangles that you attach as fixtures to the same body.
I have used approximation as well. This has some performance drawbacks, but nothing major I guess. Code (Flash ActionScript 3, but you should be able to port that easily):
var vertices:Vector.<b2Vec2> = new Vector.<b2Vec2>();
var a:Number = _image.width / 2 / PhysicsVals.RATIO;
var b:Number = _image.height / 2 / PhysicsVals.RATIO;
var segments:int = ellipse_approximation_vertices_count; (the more the more precise shape is, but the more time it takes to do collision detection)
var segment:Number = 2 * Math.PI / segments;
for (var i:int = 0; i < segments; i++)
{
vertices.push(new b2Vec2(a * Math.cos(segment * i), b * Math.sin(segment * i)));
}
var shape:b2PolygonShape = new b2PolygonShape();
shape.SetAsVector(vertices, vertices.length);
var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.shape = shape;

Detecting the Image very very slow in device

I am using this SURF code to detect the logo in my image. It is working fine but it is very slow. Any idea about how can I optimize it?
- (void)findObject
{
//NSLog(#"%# %#", self, NSStringFromSelector(_cmd));
width = 0;
CvMemStorage* storage = cvCreateMemStorage(0);
static CvScalar colors[] =
{
{{0,0,255}},
{{0,128,255}},
{{0,255,255}},
{{0,255,0}},
{{255,128,0}},
{{255,255,0}},
{{255,0,0}},
{{255,0,255}},
{{255,255,255}}
};
if( !objectToFind || !image )
{
NSLog(#"Missing object or image");
return;
}
CvSize objSize = cvGetSize(objectToFind);
IplImage* object_color = cvCreateImage(objSize, 8, 3);
cvCvtColor( objectToFind, object_color, CV_GRAY2BGR );
CvSeq *objectKeypoints = 0, *objectDescriptors = 0;
CvSeq *imageKeypoints = 0, *imageDescriptors = 0;
int i;
CvSURFParams params = cvSURFParams(500, 1);
double tt = (double)cvGetTickCount();
NSLog(#"Finding object descriptors");
cvExtractSURF( objectToFind, 0, &objectKeypoints, &objectDescriptors, storage, params );
NSLog(#"Object Descriptors: %d", objectDescriptors->total);
cvExtractSURF( image, 0, &imageKeypoints, &imageDescriptors, storage, params );
NSLog(#"Image Descriptors: %d", imageDescriptors->total);
tt = (double)cvGetTickCount() - tt;
NSLog(#"Extraction time = %gms", tt/(cvGetTickFrequency()*1000.));
CvPoint src_corners[4] = {{0,0}, {objectToFind->width,0}, {objectToFind->width, objectToFind->height}, {0, objectToFind->height}};
CvPoint dst_corners[4];
CvSize size = cvSize(image->width > objectToFind->width ? image->width : objectToFind->width,
objectToFind->height+image->height);
output = cvCreateImage(size, 8, 1 );
cvSetImageROI( output, cvRect( 0, 0, objectToFind->width, objectToFind->height ) );
//cvCopy( objectToFind, output );
cvResetImageROI( output );
cvSetImageROI( output, cvRect( 0, objectToFind->height, output->width, output->height ) );
cvCopy( image, output );
cvResetImageROI( output );
NSLog(#"Locating Planar Object");
#ifdef USE_FLANN
NSLog(#"Using approximate nearest neighbor search");
#endif
if( locatePlanarObject( objectKeypoints, objectDescriptors, imageKeypoints,
imageDescriptors, src_corners, dst_corners ))
{
for( i = 0; i < 4; i++ )
{
CvPoint r1 = dst_corners[i%4];
CvPoint r2 = dst_corners[(i+1)%4];
//cvLine( output, cvPoint(r1.x, r1.y+objectToFind->height ),
//cvPoint(r2.x, r2.y+objectToFind->height ), colors[6] );
cvLine( output, cvPoint(r1.x, r1.y+objectToFind->height ),
cvPoint(r2.x, r2.y+objectToFind->height ), colors[6],4 );
//if(i==0)
width = sqrt(((r1.x-r2.x)*(r1.x-r2.x))+((r1.y-r2.y)*(r1.y-r2.y)));
}
}
vector<int> ptpairs;
NSLog(#"finding Pairs");
#ifdef USE_FLANN
flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
#else
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
#endif
/* for( i = 0; i < (int)ptpairs.size(); i += 2 )
{
CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, ptpairs[i] );
CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( imageKeypoints, ptpairs[i+1] );
cvLine( output, cvPointFrom32f(r1->pt),
cvPoint(cvRound(r2->pt.x), cvRound(r2->pt.y+objectToFind->height)), colors[8] );
}*/
float dist = 629.0/width;
[distanceLabel setText:[NSString stringWithFormat:#"%.2f",dist]];
NSLog(#"Converting Output");
UIImage *convertedOutput = [OpenCVUtilities UIImageFromGRAYIplImage:output];
NSLog(#"Opening Stuff");
[imageView setImage:convertedOutput];
cvReleaseImage(&object_color);
[activityView stopAnimating];
}
In the above code image is my original image and objectToFind is the logo which I want to detect.
Please let me know if my question is not clear.
You need to use profiling to decide which part of your code is the slowest.
Since you are using XCode, you have a built-in profiler at hands reach:
in he top-left corner you press-and-hold "Run" button and choose "Profile".
click on Profile and and select Time Profiler.
after a while you press "stop" in the profiler, and select "Hide Missing Symbols", "Hide System Libraries" and "Top Functions", deselect "Separate by Thread".
Now look up function main and there is a hidden right arrow after it. Click on that arrow and you can see time in percent and call statistics by the calltree.
This is how you start.
In general I have the following suggestions without profiling:
Avoid creating new images and memory storages as much as you can. (You can pass images for temporary use to your function, and preserve those images outside so that you can reuse them later.)
scale down your image (and your logo) to role-out major parts of the image
use less descriptors
The two rules of thumb:
you need to decide what to improve after the profiling, as profiling often yields surprising results.
The quicker part you try to improve the less potential gain you have.