前几天发过一篇文章说怎样实现wp8下的CCLabelTTF怎样自己主动换行,后来发现果如预料的那般。效果非常不好。主要是非等宽字体的情况下看着非常糟心。因此再改动了一版。效果要好非常多了。

详细实现事实上就是參考initGlyphs,可是会不断的检查是否超过宽度。假设超过则自己主动换行。

详细的直接看代码就明确了

/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
Copyright (c) Microsoft Open Technologies, Inc. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/ #ifndef __PLATFORM_WINRT_FREETYPE_H__
#define __PLATFORM_WINRT_FREETYPE_H__ #include "platform/CCCommon.h"
#include "platform/CCImage.h"
#include <string>
#include <vector>
#include <memory> #define generic GenericFromFreeTypeLibrary
#define internal InternalFromFreeTypeLibrary
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftglyph.h>
#include <freetype/ftoutln.h>
#include <freetype/fttrigon.h>
#undef generic
#undef internal NS_CC_BEGIN typedef struct TGlyph_
{
FT_UInt index; // glyph index
FT_Vector pos; // glyph origin on the baseline
FT_Glyph image; // glyph image
} TGlyph, *PGlyph; typedef struct FontBufferInfo
{
unsigned char* pBuffer;
unsigned long size;
} FontBufferInfo; typedef struct FTWordInfo
{
std::vector<TGlyph> glyphs; // glyphs for the word
FT_BBox bbox; // bounding box containing all of the glyphs in the word
} FTWordInfo; typedef struct FTLineInfo
{
std::vector<TGlyph> glyphs; // glyphs for the line text
FT_BBox bbox; // bounding box containing all of the glyphs in the line
unsigned int width; // width of the line
FT_Vector pen; // current pen position
} FTLineInfo; class CC_DLL CCFreeTypeFont
{
public:
CCFreeTypeFont();
~CCFreeTypeFont(); bool initWithString(
const char* pText,
const char* pFontName,
int nSize,
int width,
int height
); unsigned char* getBitmap(
CCImage::ETextAlign eAlignMask,
int* outWidth,
int* outHeight
); private:
unsigned char* loadFont(const char *pFontName, unsigned long *size); unsigned char* CCFreeTypeFont::loadSystemFont(const char *pFontName, unsigned long *size); FT_Error CCFreeTypeFont::initGlyphs(const char* text); void compute_bbox(std::vector<TGlyph>& glyphs, FT_BBox *abbox); void drawText(FTLineInfo* pInfo, unsigned char* pBuffer, FT_Vector *pen); void draw_bitmap(unsigned char* pBuffer, FT_Bitmap* bitmap,FT_Int x,FT_Int y); void reset(); FT_Vector getPenForAlignment(FTLineInfo* pInfo, CCImage::ETextAlign eAlignMask, int lineNumber, int totalLines); FT_Error addLine(const std::string& line);
void newLine();
void endLine(); const std::string m_space; std::string m_text;
std::string m_fontName;
FT_Face m_face;
std::vector<FTLineInfo*> m_lines; int m_inWidth; // requested width of text box
int m_inHeight; // requested height of text box
int m_width; // final bitMap width
int m_height; // final bitMap height
int m_textWidth; // width of text text after word wrapping and line breaks
int m_textHeight; // height of text text after word wrapping and line breaks
int m_lineHeight; // height of a line for the font size
int m_windowWidth; // the width of the window FTLineInfo* m_currentLine; // the current line object to add words to.
}; NS_CC_END
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org http://cocos2d-x.org
Copyright (c) Microsoft Open Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/ #include "CCFreeTypeFont.h"
#include "CCDirector.h"
#include "platform/CCFileUtils.h" #if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
#include <dwrite.h>
#endif
#include <map>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
#include <algorithm> using namespace std; NS_CC_BEGIN static map<std::string, FontBufferInfo> s_fontsNames;
static FT_Library s_FreeTypeLibrary = nullptr; CCFreeTypeFont::CCFreeTypeFont()
:m_space(" ")
, m_face(nullptr)
{ } CCFreeTypeFont::~CCFreeTypeFont()
{
reset();
} void CCFreeTypeFont::reset()
{
for(auto line:m_lines)
{
line->glyphs.clear();
delete line;
} m_lines.clear(); if(m_face)
{
FT_Done_Face(m_face);
m_face = nullptr;
} } bool CCFreeTypeFont::initWithString(
const char* pText,
const char* pFontName,
int nSize,
int inWidth,
int inHeight )
{
FT_Error error = 0;
unsigned long size = 0;
unsigned char* pBuffer = nullptr;
unsigned char* data = nullptr; CCSize winSize = CCDirector::sharedDirector()->getWinSizeInPixels();
m_windowWidth = (int)winSize.width; m_inWidth = inWidth;
m_inHeight = inHeight; #if 0
// check the cache for the font file buffer
auto ittFontNames = s_fontsNames.find(pFontName);
if(ittFontNames != s_fontsNames.end())
{
pBuffer = ittFontNames->second.pBuffer;
size = ittFontNames->second.size;
}
#endif // 0 if(!pBuffer)
{
// attempt to load font from Resources fonts folder
pBuffer = loadFont(pFontName, &size);
if(!pBuffer)
{
// attempt to load font from System fonts folder
pBuffer = loadSystemFont(pFontName, &size);
}
if(!pBuffer)
{
// attempt to load default font from Resources fonts folder
pBuffer = loadFont("Arial", &size);
}
if(!pBuffer)
{
// attempt to load default font from System fonts folder
pBuffer = loadSystemFont("Arial", &size);
} if(!pBuffer) // font not found!
return false; #if 0
// cache the font file buffer
FontBufferInfo info;
info.pBuffer = pBuffer;
info.size = size;
s_fontsNames[pFontName]=info;
#endif // 0
} m_fontName = pFontName;
m_text = pText; if(!s_FreeTypeLibrary)
{
error = FT_Init_FreeType(&s_FreeTypeLibrary);
} if(!error && !m_face)
{
error = FT_New_Memory_Face(s_FreeTypeLibrary, pBuffer, size, 0, &m_face);
} if(!error)
{
error = FT_Select_Charmap(m_face, FT_ENCODING_UNICODE);
} if(!error)
error = FT_Set_Char_Size(m_face,nSize<<6,nSize<<6,72,72); if(!error)
error = initGlyphs(pText); delete [] pBuffer; return error == 0;
} unsigned char* CCFreeTypeFont::getBitmap(CCImage::ETextAlign eAlignMask, int* outWidth, int* outHeight)
{
int lineNumber = 0;
int totalLines = m_lines.size(); m_width = m_inWidth ? m_inWidth : m_textWidth;
m_height = m_inHeight ? m_inHeight : m_textHeight; unsigned int size = m_width * m_height * 4;
unsigned char* pBuffer = new unsigned char[size];
if(!pBuffer)
{
return nullptr;
}
memset(pBuffer, 0, size); for (auto line = m_lines.begin() ; line != m_lines.end(); ++line)
{
FT_Vector pen = getPenForAlignment(*line, eAlignMask, lineNumber, totalLines);
drawText(*line, pBuffer, &pen);
lineNumber++;
}
*outWidth = m_width;
*outHeight = m_height; reset(); return pBuffer;
} FT_Vector CCFreeTypeFont::getPenForAlignment(FTLineInfo* pInfo, CCImage::ETextAlign eAlignMask,int lineNumber, int totalLines)
{
FT_Error error = 0;
FT_Vector pen; int top;
int stringWidth = pInfo->bbox.xMax - pInfo->bbox.xMin;
int maxLineNumber = totalLines - 1;
pen.x = 0;
pen.y = 0; switch(eAlignMask)
{
case CCImage::ETextAlign::kAlignTop: // Horizontal center and vertical top.
pen.x = ((m_width - stringWidth) / 2) - pInfo->bbox.xMin;
pen.y = pInfo->bbox.yMax + (lineNumber * m_lineHeight);
break; case CCImage::ETextAlign::kAlignTopLeft: // Horizontal left and vertical top.
pen.x -=pInfo->bbox.xMin;
pen.y = pInfo->bbox.yMax + (lineNumber * m_lineHeight);
break; case CCImage::ETextAlign::kAlignTopRight: // Horizontal right and vertical top.
pen.x = m_width - stringWidth - pInfo->bbox.xMin;
pen.y = pInfo->bbox.yMax + (lineNumber * m_lineHeight);
break; case CCImage::ETextAlign::kAlignBottomRight: // Horizontal right and vertical bottom.
pen.x = m_width - stringWidth - pInfo->bbox.xMin;
pen.y = m_height + pInfo->bbox.yMin - ((maxLineNumber - lineNumber) * m_lineHeight);
break; case CCImage::ETextAlign::kAlignBottom: // Horizontal center and vertical bottom.
pen.x = ((m_width - stringWidth) / 2) - pInfo->bbox.xMin;
pen.y = m_height + pInfo->bbox.yMin - ((maxLineNumber - lineNumber) * m_lineHeight);
break; case CCImage::ETextAlign::kAlignBottomLeft: // Horizontal left and vertical bottom.
pen.x -=pInfo->bbox.xMin;
top = (m_height - m_textHeight) / 2;
pen.y = m_height + pInfo->bbox.yMin - ((maxLineNumber - lineNumber) * m_lineHeight);
break; case CCImage::ETextAlign::kAlignCenter: // Horizontal center and vertical center
pen.x = ((m_width - stringWidth) / 2) - pInfo->bbox.xMin;
top = (m_height - m_textHeight) / 2;
pen.y = top + (lineNumber * m_lineHeight) + pInfo->bbox.yMax;
break; case CCImage::ETextAlign::kAlignRight: // Horizontal right and vertical center.
pen.x = m_width - stringWidth - pInfo->bbox.xMin;
top = (m_height - m_textHeight) / 2;
pen.y = top + (lineNumber * m_lineHeight) + pInfo->bbox.yMax;
break; case CCImage::ETextAlign::kAlignLeft: // Horizontal left and vertical center.
default:
pen.x -=pInfo->bbox.xMin;
top = (m_height - m_textHeight) / 2;
pen.y = top + (lineNumber * m_lineHeight) + pInfo->bbox.yMax;
break;
} return pen;
} void CCFreeTypeFont::drawText(FTLineInfo* pInfo, unsigned char* pBuffer, FT_Vector *pen)
{ auto glyphs = pInfo->glyphs;
for (auto glyph = glyphs.begin() ; glyph != glyphs.end(); ++glyph)
{
FT_Glyph image = glyph->image;
FT_Error error = FT_Glyph_To_Bitmap(&image, FT_RENDER_MODE_NORMAL, 0, 1);
if (!error)
{
FT_BitmapGlyph bit = (FT_BitmapGlyph)image;
draw_bitmap(pBuffer, &bit->bitmap, pen->x + glyph->pos.x + bit->left,pen->y - bit->top);
FT_Done_Glyph(image);
}
}
} void CCFreeTypeFont::draw_bitmap(unsigned char* pBuffer, FT_Bitmap* bitmap, FT_Int x, FT_Int y)
{
FT_Int i, j, p, q;
FT_Int x_max = x + bitmap->width;
FT_Int y_max = y + bitmap->rows; for (i = x, p = 0; i < x_max; i++, p++)
{
for ( j = y, q = 0; j < y_max; j++, q++ )
{
if (i < 0 || j < 0 || i >= m_width || j >= m_height)
continue; unsigned char value = bitmap->buffer[q * bitmap->width + p]; if(value > 0)
{
FT_Int index = (j * m_width * 4) + (i * 4);
pBuffer[index++] = 0xff;
pBuffer[index++] = 0xff;
pBuffer[index++] = 0xff;
pBuffer[index++] = value;
}
}
}
} void CCFreeTypeFont::endLine()
{
if(m_currentLine)
{
m_lines.push_back(m_currentLine);
compute_bbox(m_currentLine->glyphs, &m_currentLine->bbox);
m_currentLine->width = m_currentLine->bbox.xMax - m_currentLine->bbox.xMin;
m_textWidth = max(m_textWidth,m_currentLine->bbox.xMax - m_currentLine->bbox.xMin);
m_textHeight += m_lineHeight;
m_currentLine = NULL;
}
} void CCFreeTypeFont::newLine()
{
m_currentLine = new FTLineInfo();
m_currentLine->width = 0;
m_currentLine->pen.x = 0;
m_currentLine->pen.y = 0;
} FT_Error CCFreeTypeFont::addLine(const std::string& line)
{
wchar_t * pwszBuffer = nullptr; int num_chars = line.size();
int nBufLen = num_chars + 1;
pwszBuffer = new wchar_t[nBufLen];
if (!pwszBuffer)
{
return -1;
} memset(pwszBuffer, 0, nBufLen);
num_chars = MultiByteToWideChar(CP_UTF8, 0, line.c_str(), num_chars, pwszBuffer, nBufLen);
pwszBuffer[num_chars] = '\0'; int maxWidth = m_inWidth ? m_inWidth : m_windowWidth; newLine();
FT_Vector pen = m_currentLine->pen;
FT_GlyphSlot slot = m_face->glyph;
FT_UInt glyph_index;
FT_UInt previous = 0;
FT_Error error = 0;
unsigned int numGlyphs = 0; FT_Bool useKerning = FT_HAS_KERNING(m_face); int n = 0;
while (n < num_chars)
{
TGlyph glyph; /* convert character code to glyph index */
FT_ULong c = pwszBuffer[n++];
glyph_index = FT_Get_Char_Index(m_face, c); if (useKerning && previous && glyph_index)
{
FT_Vector delta;
FT_Get_Kerning(m_face, previous, glyph_index,
FT_KERNING_DEFAULT, &delta);
pen.x += delta.x >> 6;
} /* store current pen position */
glyph.pos = pen;
glyph.index = glyph_index; /* load glyph image into the slot without rendering */
error = FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);
if (error)
continue; /* ignore errors, jump to next glyph */ /* extract glyph image and store it in our table */
error = FT_Get_Glyph(m_face->glyph, &glyph.image);
if (error)
continue; /* ignore errors, jump to next glyph */ /* translate the glyph image now */
FT_Glyph_Transform(glyph.image, 0, &glyph.pos); /* increment pen position */
pen.x += slot->advance.x >> 6; if (pen.x > maxWidth)
{
m_currentLine->pen = pen;
endLine(); newLine();
pen = m_currentLine->pen;
previous = 0;
n--;
}
else
{
m_currentLine->glyphs.push_back(glyph);
/* record current glyph index */
previous = glyph_index;
}
} if (m_currentLine)
{
m_currentLine->pen = pen;
endLine();
} CC_SAFE_DELETE_ARRAY(pwszBuffer);
return error;
} FT_Error CCFreeTypeFont::initGlyphs(const char* text)
{
FT_Error error = 0;
std::stringstream stringStream(text);
std::string line; m_textWidth = 0;
m_textHeight = 0;
// the height of a line of text based on the max height of a glyph in the font size
m_lineHeight = ((m_face->size->metrics.ascender) >> 6) - ((m_face->size->metrics.descender) >> 6); m_lines.clear(); while(std::getline(stringStream, line) && !error)
{
addLine(line);
} return error;
} void CCFreeTypeFont::compute_bbox(std::vector<TGlyph>& glyphs, FT_BBox *abbox)
{
FT_BBox bbox;
FT_BBox glyph_bbox; /* initialize string bbox to "empty" values */
bbox.xMin = 32000;
bbox.xMax = -32000; // use the max and min values for the entire font face
bbox.yMin = (m_face->size->metrics.descender) >> 6;
bbox.yMax = (m_face->size->metrics.ascender) >> 6; /* for each glyph image, compute its bounding box, */
/* translate it, and grow the string bbox */
for (auto glyph = glyphs.begin() ; glyph != glyphs.end(); ++glyph)
{
FT_Glyph_Get_CBox(glyph->image, ft_glyph_bbox_pixels, &glyph_bbox); glyph_bbox.xMin += glyph->pos.x;
glyph_bbox.xMax += glyph->pos.x;
glyph_bbox.yMin += glyph->pos.y;
glyph_bbox.yMax += glyph->pos.y; if (glyph_bbox.xMin < bbox.xMin)
bbox.xMin = glyph_bbox.xMin; if (glyph_bbox.yMin < bbox.yMin)
bbox.yMin = glyph_bbox.yMin; if (glyph_bbox.xMax > bbox.xMax)
bbox.xMax = glyph_bbox.xMax; if (glyph_bbox.yMax > bbox.yMax)
bbox.yMax = glyph_bbox.yMax;
} /* check that we really grew the string bbox */
if (bbox.xMin > bbox.xMax)
{
bbox.xMin = 0;
bbox.yMin = 0;
bbox.xMax = 0;
bbox.yMax = 0;
} /* return string bbox */
*abbox = bbox;
} unsigned char* CCFreeTypeFont::loadFont(const char *pFontName, unsigned long *size)
{
std::string lowerCase(pFontName);
std::string path(pFontName); for (unsigned int i = 0; i < lowerCase.length(); ++i)
{
lowerCase[i] = tolower(lowerCase[i]);
} if (std::string::npos == lowerCase.find("fonts/"))
{
path = "fonts/";
path += pFontName;
} if (std::string::npos == lowerCase.find(".ttf"))
{
path += ".ttf";
} std::string fullpath = CCFileUtils::sharedFileUtils()->fullPathForFilename(path.c_str());
return CCFileUtils::sharedFileUtils()->getFileData(fullpath.c_str(), "rb", size);
} unsigned char* CCFreeTypeFont::loadSystemFont(const char *pFontName, unsigned long *size)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
return nullptr;
#else
std::string aName(pFontName);
unsigned char* pBuffer = nullptr;
HRESULT hr = S_OK;
IDWriteFactory *writeFactory = nullptr;
IDWriteFontCollection *fontCollection = nullptr;
IDWriteFontFamily *fontFamily = nullptr;
IDWriteFont *matchingFont = nullptr;
IDWriteFontFace *fontFace = nullptr;
IDWriteFontFile *fontFile = nullptr;
IDWriteFontFileLoader *fontFileLoader = nullptr;
IDWriteFontFileStream *fontFileStream = nullptr;
UINT32 index;
BOOL exists;
std::wstring fontNameW;
const void *fontFileReferenceKey = nullptr;
UINT32 fontFileReferenceKeySize;
void *fragmentContext = nullptr; for (unsigned int i = 0; i < aName.length(); ++i)
{
aName[i] = tolower(aName[i]);
}
fontNameW.assign(aName.begin(), aName.end()); //create the factory
hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&writeFactory)); if(SUCCEEDED(hr))
{
//obtain the fonts owned by the machine
hr = writeFactory->GetSystemFontCollection(&fontCollection, TRUE);
} //get the font
if(SUCCEEDED(hr))
{
hr = fontCollection->FindFamilyName(fontNameW.c_str(), &index, &exists);
if(SUCCEEDED(hr) && exists)
{
hr = fontCollection->GetFontFamily(index, &fontFamily); if(SUCCEEDED(hr))
{
hr = fontFamily->GetFirstMatchingFont(DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &matchingFont);
} if(SUCCEEDED(hr))
{
hr = matchingFont->CreateFontFace(&fontFace);
} if(SUCCEEDED(hr))
{
UINT32 numberOfFiles = 1;
hr = fontFace->GetFiles(&numberOfFiles, &fontFile);
} if(SUCCEEDED(hr))
{
//create the font file stream
hr = fontFile->GetReferenceKey(&fontFileReferenceKey, &fontFileReferenceKeySize);
} if(SUCCEEDED(hr))
{
hr = fontFile->GetLoader(&fontFileLoader);
} if(SUCCEEDED(hr))
{
hr = fontFileLoader->CreateStreamFromKey(fontFileReferenceKey, fontFileReferenceKeySize, &fontFileStream);
} if(SUCCEEDED(hr))
{
//finally get the font file dat
UINT64 fileSize;
const void *fragmentStart = nullptr;
hr = fontFileStream->GetFileSize(&fileSize); if(SUCCEEDED(hr))
{
hr = fontFileStream->ReadFileFragment(&fragmentStart, 0, fileSize, &fragmentContext);
} if(SUCCEEDED(hr))
{
pBuffer = (unsigned char*)malloc((size_t)fileSize);
memcpy(pBuffer, fragmentStart, (size_t)fileSize);
*size = (unsigned long)fileSize;
}
}
}
} //clean up all the DWrite stuff
if(fontFileStream)
{
fontFileStream->ReleaseFileFragment(fragmentContext);
fontFileStream->Release();
}
if(fontFileLoader)
{
fontFileLoader->Release();
}
if(fontFile)
{
fontFile->Release();
}
if(fontFace)
{
fontFace->Release();
}
if(matchingFont)
{
matchingFont->Release();
}
if(fontFamily)
{
fontFamily->Release();
}
if(fontCollection)
{
fontCollection->Release();
}
if(writeFactory)
{
writeFactory->Release();
} return pBuffer;
#endif
} NS_CC_END

cocos2dx windows phone平台下CCLabelTTF自己主动换行的实现(2)的更多相关文章

  1. [修正] Firemonkey Windows & macOS 平台下 Edit & Memo 中文输入后会取消原选取文字的 BUG

    问题:Firemonkey Windows & macOS 平台下 Edit & Memo 中文输入后会取消原选取文字的 BUG 适用版本:Delphi 10.1.2 & 10 ...

  2. 开发Windows RT平台下的Windows应用商店应用程序的遇到的问题备忘

    1. 关于获取Win8开发者许可证的问题: 有一种情况是:如果系统是Win8.0, 那么如果先激活了windows8(用激活工具), 再安装VS2012,那么在新建项目时会提示获取windows8开发 ...

  3. Windows平台下Git服务器搭建--------gitblit

    Windows(server)平台下Git服务器搭建 第一步:下载Java,安装,配置环境变量. 第二步:下载Gitblit.下载地址:http://www.gitblit.com/ 第三步:解压缩下 ...

  4. [转]Windows平台下Makefile学习笔记

    Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...

  5. Windows平台下Git服务器搭建

    第一步:下载Java,下载地址:http://www.java.com/zh_CN/ 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键”计算机” => ”属性” = ...

  6. Windows平台下PHP开发环境的配置

    Windows平台下PHP开发环境的配置 一.基本环境 1.Windows XP 32位 2.Apache 2.2.25,下载地址:http://mirror.bit.edu.cn/apache/ht ...

  7. Mac平台与Windows平台下AndroidStudio增量升级

    Android Studio增量升级什么情况下使用最合适呢? 比如现在的as版本是2.2版本,而你的as版本2.0版本,这个时候点Check For Updates就没有反应了,因为你已经2个有版本没 ...

  8. Windows 平台下Git 服务器搭建

    由于项目中一直在使用git作为版本管理,自己对git的理解.使用都还不是怎么的熟悉,所以准备深入了解一下git及一些常用命令的使用,于是干脆把服务端架上,通过自己的PC作为服务端同时作为客户端的角色进 ...

  9. windows平台下VLC2.0.5编译

    windows平台下VLC2.0.5编译说明 时隔一年多,又要搞流媒体了,不过这次是要做流媒体服务器. 暂时决定使用vlc+ffmpeg+live555,虽然听有些前辈说这个组合的性能较差,只能作为学 ...

随机推荐

  1. Android 签名(3)已签名的apk中的文件

    已经签名 apk包中签名相关的文件在meta_INF目录下 CERT.SF:生成每个文件相对的密钥 MANIFEST.MF:数字签名信息 xxx.SF:这是JAR文件的签名文件,占位符xxx标识了签名 ...

  2. UVa 201 Squares

    题意: 给出这样一个图,求一共有多少个大小不同或位置不同的正方形. 分析: 这种题一看就有思路,最开始的想法就是枚举正方形的位置,需要二重循环,枚举边长一重循环,判断是否为正方形又需要一重循环,复杂度 ...

  3. php简单实现MVC

    在PHP中使用MVC越来越流行了,特别是在一些开源的框架当中.MVC足以应对大多数的情况,但还有一些情况是其不太适合的,如比较简单的个人博客,对于只有几百篇文章量级的博客,使用MVC让人觉得有些太复杂 ...

  4. Hibernate4.x之Session--常用方法

    接上篇文章继续学习Hibernate的Session(http://www.cnblogs.com/dreamfree/p/4111777.html) 持久化对象的状态; 站在持久化的角度,Hiber ...

  5. Entity Framework Code First级联删除

    如果我们要到一对主从表增加级联删除,则要在主表中的引用属性上增加Required关键字,如: public class Destination { public int DestinationId { ...

  6. 使用selector修改TextView中字体的颜色

    selector想必大家都用过了,但是在修改字体的颜色的时候还是要细心. 我们在TextView中设置字体颜色一般使用 android:textColor="@color/red" ...

  7. codeforces 671B Robin Hood 二分

    题意:有n个人,每个人a[i]个物品,进行k次操作,每次都从最富有的人手里拿走一个物品给最穷的人 问k次操作以后,物品最多的人和物品最少的人相差几个物品 分析:如果次数足够多的话,最后的肯定在平均值上 ...

  8. Linux下复制粘贴快捷键

    1. 在控制台下:            1.1.鼠标选中要复制的文本,按鼠标中键,即为复制                              或者              1.2.复制命令 ...

  9. mysql日期加减问题

    有一个date列,我想修改下,让该列里每个日期都加上7天,怎么写代码?  update [表名] set date=date_add(date, interval 7 day); SELECT * f ...

  10. 【转】SQL中Group By的使用

    1.概述 2.原始表 3.简单Group By 4.Group By 和 Order By 5.Group By中Select指定的字段限制 6.Group By All 7.Group By与聚合函 ...